import pandas as pd

"""
Explanation: My notebook to practics Pandas
This is some notes
End of explanation
"""


## difference between loc and iloc
vals = [0, 1, 2]
idx = [10, 11, 12]
ser = pd.Series(vals, index=idx)

print("...using loc")
print(ser.loc[10:11])
print("\n...using iloc")
print(ser.iloc[0:2])

## creating series
vals = [0, 1, 2, 3]
idx = ['a', 'b', 'c', 'd']
ser = pd.Series(vals, index=idx)
print(ser)
print("\n...single index")
print(ser.loc['a'])
print("\n...a slice")
print(ser.loc['a':'c'])

"""
Explanation: Working with series

loc uses the specified index and it is inclusive
iloc uses the python index and is exclusive
End of explanation
"""


## from a list of lists
vals = [[1,2,3], [4,5,6]]
cols = ['a', 'b', 'c']
df = pd.DataFrame(data=vals, columns=cols)
df

## from a list of dictionaried
rows = [{'a': 1, 'b': 2, 'c':3}, {'a': 4, 'b': 5, 'c':6}]
df = pd.DataFrame(rows)
df

## how does pandas deal with missing numeric values
vals = [[10, 11], [20, 21, 22]]
cols = ['a', 'c', 'd']
df = pd.DataFrame(data=vals, columns=cols)
df

## how does pandas deal with missing string values
vals = [['z', 'y'], ['x', 'w', 'v']]
cols = ['a', 'c', 'd']
df = pd.DataFrame(data=vals, columns=cols)
df

df.transpose()

df

## dealing with missing data
vals = [[10, 11], [20, 21, 22]]
cols = ['a', 'c', 'd']
df1 = pd.DataFrame(data=vals, columns=cols)
df1.dropna(inplace=True)
df1

## fill them in with something
df2 = pd.DataFrame(data=vals, columns=cols)
df2.fillna(-1, inplace=True)
df2

"""
Explanation: Working with Data Frames

can create from a list of lists
can do it from a dictionaries
or you can import from somewhere like a csv
End of explanation
"""


df = pd.read_csv('winequality-red.csv', delimiter=';')
df.head()

import pprint
print("Shape of my data frame: {} x {}".format(df.shape[0],df.shape[1]))
df.describe()

import re

## clean up the column names
cols = df.columns.tolist()
df.columns = [re.sub("\s+","_",col) for col in df.columns.tolist()]

## print the columns description
print("Shape of my data frame: {} x {}".format(df.shape[0],df.shape[1]))
pp = pprint.PrettyPrinter(indent=2)
pp.pprint(list(df.columns))

## basic statistical calculations
df.describe()

"""
Explanation: reading csv file
End of explanation
"""


## single column reference returns a slice
a_column = df['fixed_acidity']
print(type(a_column))

## multiple column references returns another dataframe
some_columns = df[['fixed_acidity','citric_acid']]
print(type(some_columns))

## get rows from a given column using loc
df.loc[100:102, 'fixed_acidity']

## get rows from a given column using iloc
df['fixed_acidity'].iloc[100:102]

## get rows from a multiple columns using iloc
df[['fixed_acidity','chlorides']].iloc[100:102]

"""
Explanation: Slicing
End of explanation
"""


df_quality = df.groupby("quality")
df_quality.mean()

"""
Explanation: Groupbys
End of explanation
"""


mask = df['alcohol'] > 12.0
df1 = df[mask]
df1.groupby("quality").mean()

## multiple conditionals 
df[(df['alcohol'] > 12.0) & (df['quality'] > 5)].groupby("quality").mean()

## Can also use query to evaluate conditionals
result_df = df.query('alcohol >= 9.10 and pH < 3.5')
result_df.loc[1:6, ['alcohol', 'pH']]

"""
Explanation: Conditionals
Note that we use the & and | to string conditionals together because we use NumPy's masking rules
End of explanation
"""


## single column sort
df.sort_values(by='fixed_acidity', ascending=True)

## multicolumn sort
df.sort_values(by=['fixed_acidity', 'volatile_acidity'], ascending=True)

"""
Explanation: Sorting
End of explanation
"""


df.drop('sulphates', axis=1, inplace=True)
df.info()

## Using eval
df.eval('total_acidity = volatile_acidity + fixed_acidity', inplace=True)
df[['total_acidity', 'volatile_acidity', 'fixed_acidity']].head()

"""
Explanation: Dropping and adding columns

The argument axis=1 means that we are droppinng a column.
The argument inplace=True tells it to modify the dataframe

If we used inplace==False then it would return a copy that we could use, but the original would remain unmodified.
End of explanation
"""


