import pandas as pd

df = pd.read_csv('../data/tidy_who.csv')

"""
Explanation: Data exploration
We use the dataset found at https://github.com/mkcor/data-wrangling/blob/master/data/tidy_who.csv
(see the notebook at the root of that repo for the generation of this dataset).
End of explanation
"""


df.head()

df.shape

df.sample(10)

df.describe()

df['g_whoregion'].unique()

df['country'].nunique()

"""
Explanation: Loading data
... just works. read_csv() comes with many convenient arguments, such as skiprows, nrows, na_values, etc. Note that, alternatively, we could have run df = pd.read_csv('https://raw.githubusercontent.com/mkcor/data-wrangling/master/data/tidy_who.csv').
End of explanation
"""


df['country'].head(3)

"""
Explanation: Selecting data
We are already familiar with column selection. The [ ] syntax is the most basic way of indexing.
End of explanation
"""


df.country[1000:1003]

"""
Explanation: Columns can also be accessed as attributes (as long as they have a valid Python name).
End of explanation
"""


df.loc[0, 'country']

df.loc[df.shape[0] - 1, 'country']

df.iloc[0, 0]

df.iloc[df.shape[0] - 1, 0]

"""
Explanation: We can select elements of a DataFrame either by label (with the .loc attribute) or by position (with the .iloc attribute). Row and column indices take the usual order (first and second place, respectively).
End of explanation
"""


df.loc[:5, 'country']

"""
Explanation: Slicing works too.
End of explanation
"""


df.loc[:5, 'country':'type']

df.iloc[:5, :5]

"""
Explanation: Label indexing is more natural than positional indexing (think of a function call, where keyword arguments are easier to work with than positional arguments).
End of explanation
"""


cond = df.year < 1981

df[cond].shape

df[cond & (df.country == 'Argentina') & (df.type == 'rel') & (df.sex == 'm')]

gr_and_it = df.country.isin(['Greece', 'Italy'])

df[gr_and_it].tail()

"""
Explanation: Often we want to select data based on certain conditions.
End of explanation
"""


lambda x: ['country', 'g_whoregion']

"""
Explanation: Subsets can be selected by callable functions (returning valid indexers).
The following function performs a selection by label (along country and g_whoregion).
End of explanation
"""


df.loc[:3, lambda x: ['country', 'g_whoregion']]

"""
Explanation: So it can serve as a column indexer.
End of explanation
"""


lambda x: x.cases > 100000

"""
Explanation: The following function filters for data where the number of cases is greater than 100,000.
End of explanation
"""


great = df.loc[lambda x: x.cases > 100000, :]
great

df.cases.loc[lambda x: x > 100000]

"""
Explanation: So it can serve as a row indexer.
End of explanation
"""


great.where(great.country == 'India')

great.mask(great.country == 'India')

"""
Explanation: We may want to select or mask data while preserving the original shape.
End of explanation
"""


df1 = df[(df.country == 'Greece') & (df.year == 2000) & (df.age_range.isin([14, 1524]))]

df1.to_csv('../data/df1.csv')

df2 = pd.read_csv('../data/df1.csv')

"""
Explanation: Hands-on exercises

Select the rows of df where country is Greece, age is at most 24, and year is 2000. Name it df1.
Write the df1 DataFrame to a CSV file located in the data/ subdirectory. (Hint: The method is named to_csv.)
Read this CSV file into a DataFrame named df2. What do you notice about the index? (Feel free to fire up a Terminal and look at the CSV file.)
End of explanation
"""


df1.index

df2.index

"""
Explanation: Indexing
End of explanation
"""


pd.read_csv('../data/df1.csv', index_col=0)

"""
Explanation: We could specify that the first (unnamed) column should be used as the index (row labels).
End of explanation
"""


df1.reset_index()

"""
Explanation: Remember we learnt set_index() in the previous section? We also have reset_index() at our disposal.
End of explanation
"""


df1.reset_index().index

"""
Explanation: And we are back to a default index for this DataFrame. The original index is stored in its own column.
End of explanation
"""


