"""
# Introduction to Pandas
---
"""
"""

Pandas is an open-source easy-to-use python library for data manipulation and analysis.
"""
"""
DataFrame is a 2-dimensional labeled data structure with columns of potentially different types. You can think of it like a spreadsheet or SQL table, or a dictionary of Series objects. 
"""
"""
#Series : First main data type in Pandas
"""
import pandas as pd
labels =['a','b','c']
my_data=[10,20,30]

d={'a':10,'b':10,'c':30}
pd.Series(d)
"""
#DataFrame
"""
import numpy as np

x=np.random.randint(100,size=(5,4)) 
print("Numpy Array:")
x
import pandas as pd
df = pd.DataFrame(x)
print("Pandas DataFrame:")
df
df = pd.DataFrame(x,['x','b','c','d','e'],['W','X','Y','Z'])
print("Pandas DataFrame with custom indexing:")
df
df['X']
#ENTERING ANATHER COLUMN IN A DATAFRAME
df['new_col']=[1,2,3,4,5]
df
#how delete column in dataframe:
df.drop('Y',axis=1,inplace=True)
print(df)
#how delete column in dataframe:
df.drop('c',axis=0,inplace=True)
print(df)
"""
#Importing pandas library and reading a CSV file into a dataframe.
"""
 df = pd.read_csv('/kaggle/input/sales-dataset-cse422csv/Sales Data (CSE422_ Pandas) - sales.csv',index_col='month')
 df.head()
"""
# Indexing DataFrames
 
"""
"""
## Indexing using square brackets
"""
df = pd.read_csv('/kaggle/input/sales-dataset-cse422csv/Sales Data (CSE422_ Pandas) - sales.csv',index_col='month')
df.head()
 df['eggs']['Mar'] # df[column]['rows']
 type(df)
df.eggs['Apr']
"""
Using column atribute and row index/label
"""
df.salt['Apr']
"""
Selecting only some columns
"""
df_new = df[['salt','spam']]
df_new
"""
Selecting a column (i.e., Series)
"""
 df['eggs'] 
#printing type of the column selected
type(df['eggs'])
"""
Slicing and indexing a Series
"""
#selecting part of a series
df['eggs'][1:4]
df['eggs'][4] 
"""
# Slicing DataFrames
"""
"""
Using the .loc accessor
* Access a group of rows and columns by label(s) or a boolean array.
"""
"""
A series is a 1D-array that can store any data type
"""
"""
* LOC is not based on index. The stop limit is **not** exclusive
* ILOC is based on index. The stop limit is exclusive
"""
#we can access row by 2 ways:
# 1. location based selection .loc('rowname')
# 2. numerical based selection  iloc(rowindex)
df2 = pd.DataFrame(x,['x','b','c','d','e'],['W','X','Y','Z'])
df2.loc[:,'X']
df
df.loc['Feb':'Mar','eggs':'salt']
df.loc['Feb',:]   #df.loc[rows,column] 
 df.loc['Jan': 'Mar', ['eggs','spam']] 
df.loc[:, ['eggs','salt']]   # All rows, some columns 
 df.loc['Jan':'Apr',:]  # Some rows, all columns 
df.loc['Mar':'May', 'salt':'spam'] 
"""
Using the .iloc accessor
* Purely integer-location based indexing for selection by position.
"""
df
df.iloc[2]  #indexwise
df.iloc[2,2]
 df.iloc[2:4, 2]
 df
df.iloc[2:5, 1:] # A block from middle of the DataFrame 
"""
Using lists rather than slices (1)
"""
df.loc['Jan':'May', ['eggs','salt']]   
"""
Using lists rather than slices (2)
"""
df.iloc[[0,4,5], 0:2] 
"""
Series versus 1-column DataFrame
"""
 df['eggs']
 
type(df['eggs'])
df[['eggs']] 
type(df[['eggs']]) 
"""
#Filtering DataFrames
"""
"""
Creating a Boolean Series
"""
df
df['salt'] > 60
"""
Filtering with a Boolean Series
"""
df.salt > 60
a = df.salt > 60
type(a) #this is a series
df[a]
df[df.salt>60]
"""
Combining filters
"""
(df.salt >= 50) & (df.eggs < 200)
 df[(df.salt >= 50) & (df.eggs < 200)] # Both conditions
(df.salt >= 50) | (df.eggs < 200)
 df[(df.salt >= 50) | (df.eggs < 200)] # Either condition
"""
#DataFrame Append
"""
df2 = df.copy()
df2
 df2['bacon']=[0,0,60,0,90,100]
 df2
df3=df2.copy()
df3
other = pd.DataFrame({'eggs': ['K0', 'K1', 'K2'],
                      'salt': ['b10', 'b20', 'b50'],
                      'spam': ['s1', 's2', 's3'],
                      'bacon': ['bc0', 'bc1', 'cb2']},index=["July", "Aug", "Sept"])
other
df2.append(other)
df3
df3.columns=['X', 'Y', 'Z','T']
df3
df3.drop("T",axis=1,inplace=True)
df3
"""
#DataFrames with zeros and NaNs
"""
"""
Select columns with all nonzeros
"""
df
df['bacon']=[0,0,0,0,0,1]
df['bacon'].any()
df
df.loc[:, df.all()] 
"""
Select columns with any NaNs
"""
df.loc[:, df.isnull().any()]
"""
Select columns without NaNs
"""
df
df.loc[:, df.notnull().any()] 
"""
Drop rows with any NaNs
"""
df.dropna(how='any') 
df
df.salt > 55
"""
Filtering a column based on another
"""
df.eggs[df.salt > 55]  #returns a series