import pandas as pd
import numpy as np

"""
Explanation: Pandas basic

uses dataframe to put data in easy to use format
SQL like - relational
fast read right from storage
End of explanation
"""


# DataFrame from dict
students = pd.DataFrame( {
    'phone': ['123-1234', '321-4321', '321-4321'],
    'age': [13, 12, 13],
    'grade': [78, 77, 92]}, 
    index = ['alice', 'bob', 'eve'] )
students

students.index

# Dataframe from numpy array
df = pd.DataFrame(np.random.randn(6,4), 
                  index=['index1', 'index2', 'index3', 'index4','index5','index6'], 
                  columns = list('ABCD'))
df


"""
Explanation: creating dataframe

from dict
from numpy array
from csv
from fwf
End of explanation
"""


#first few lines
df.head()

df.head(3)

#last few lines
df.tail()

df.tail(2)

"""
Explanation: DataFrame from csv file
load csv --> df = pd.read_csv('./PWD/file.csv', delimiter="\t")    
save csv --> df.to_csv('./PWD/newFile.csv  ')
fwf with time series
data = pd.read_fwf('location/file.txt', 
                   header=None, 
                   index_col=0, 
                   parse_dates=[[0,1]], infer_datetime_format=True)
End of explanation
"""


# type of data
type(df)

# number of rows and columns
df.shape

# information about data
df.info()

df.describe()

"""
Explanation: Understanding data
End of explanation
"""


# series --> 1D set of data with an index
s = pd.Series([1, 3, 4, np.nan, 4, 2])
s

# adding index later
s.index = ['a','b','c','d','e', 'f']
s

# Missing data
s.isnull()

"""
Explanation: Series
End of explanation
"""


# plotting 
import matplotlib.pyplot as plt
%matplotlib inline

s.plot()

df.plot()

"""
Explanation: Plotting
End of explanation
"""


# see portion of data in dataframe or series
s[s.index > 'c']

s[s.isnull() == False]

df.head()

# select column
df.A

df['B']

# column types
df.dtypes

# column names
df.columns

# multiple columns
df[ ['A','B']]

# number of rows
df.shape[0]

# select label / name
df.loc['index2']

# label and column intersection
df.loc['index3', ['A', 'C']]

# select by label location/ index
df.iloc[1,3]

# get rows by name or number
df.ix[0]

df.ix[ ['index2', 'index1' ]]

# df.ix[row, column]
df.ix[ [0,3], ['A', 'D']]

df.iloc[3, :]

df.iloc[:, 2]

# add column to dataframe
df['Z'] = [1,3,4,5,6,8]
df

df[df['A'] == df['A'].max()]

"""
Explanation: selecting data
End of explanation
"""


#function
df.Z.apply(lambda Z: Z + 0.1)

#built-in
df.A.mean()

df.A.max()

df.A.min()

df.count()

#correlation between columns
df.corr()

# cummulative max
df.cummax()

"""
Explanation: function
End of explanation
"""


students

# aggregation: mean grade grouped by age
students.groupby('age')['grade'].mean()

#bins
bin = np.linspace(70, 100, 4)
bin

# grades grouped by 70s 80s and 90s and age of students
students.groupby( np.digitize(students.grade, bin)).age.mean()

"""
Explanation: aggregation
End of explanation
"""


num = list(range(20))

num

# num[ start: end: jump]
num[ : : 2]

num[ 15: 1 : -3]

"""
Explanation: more indexing
End of explanation
"""


