Pandas是用於數據操縱和分析,建立在Numpy之上的。Pandas為Python帶來了兩種新的數據結構:Pandas Series和Pandas DataFrame,借助這兩種數據結構,我們能夠輕松直觀地處理帶標簽數據和關系數據。
Pandas功能:
- 允許為行和列設定標簽
- 可以針對時間序列數據計算滾動統計學指標
- 輕松處理NaN值
- 能夠將不同的數據集合並在一起
- 與Numpy和Matplotlib集成
Pandas Series
Pandas series 是像數組一樣的一維對象,可以存儲很多類型的數據。Pandas series 和 Numpy array之間的主要區別之一是你可以為Pandas series 中的每個元素分配索引標簽;另一個區別是Pandas series 可以同時存儲不同類型的數據。
創建 Pandas Series
pd.Series(data, index)
1 groceries = pd.Series(data=[30, 6, 'yes', 'No'], index=['eggs', 'apples', 'milk', 'bread']) 2 ser = pd.Series(data=[[0, 1, 2, 3], [1, 3, 5, 7], [2, 4, 6, 8]], index=(['a', 'b', 'c']))
查看 Pandas Series 屬性
print(groceries.size) # 數量
print(groceries.shape) # 形狀
print(groceries.ndim) # 維度
print(groceries.index) # 索引列表
print(groceries.values) # 元素列表
查看是否存在某個索引標簽:in
1 print('book' in groceries)
訪問 Pandas Series 中元素切片和索引
Pandas Series 提供了兩個屬性 .loc 和 .iloc
.loc 表明我們使用的是標簽索引訪問
.iloc 表明我們使用的是數字索引訪問
# 標簽索引 print(groceries['eggs']) print(groceries[['eggs', 'milk']]) # 數字索引 print(groceries[1]) print(groceries[[1, 2]]) print(groceries[-1]) # 明確標簽索引 print(groceries.loc['milk']) print(groceries.loc[['eggs', 'apples']]) # 明確數字索引 print(groceries.iloc[0]) print(groceries.iloc[[0, 1]])
可以使用groceries.head(),tail()分別查看前n個和后n個值
groceries.unique進行去重操作
修改和刪除 Pandas Series 中元素
直接標簽訪問,值修改就可
1 groceries['eggs'] = 2 2 print(groceries)
刪除:drop(參數 1:lable,標簽;參數 2:inplace=True/False,是/否修改原 Series)
1 print(ser.drop(['b'])) 2 print(ser.drop(['a', 'b'], inplace=True))
Pandas Series 中元素執行算術運算
Pandas Series執行元素級算術運算:加、減、乘、除
fruits = pd.Series(data=[10, 6, 3], index=['apples', 'oranges', 'bananas']) # 所有數字進行運算 print(fruits + 2) print(fruits - 2) print(fruits * 2) print(fruits / 2) # 所有元素應用Numpy中的數學函數 print(np.exp(fruits)) print(np.sqrt(fruits)) print(np.power(fruits, 2)) # 部分元素進行運算 print(fruits[0] - 2) print(fruits['apples'] + 2) print(fruits.loc['oranges'] * 2) print(np.power(fruits.iloc[0], 2))
Pandas DataFrame
DataFrame是一個【表格型】的數據結構。DataFrame由按一定順序排列的多列數據組成。設計初衷是將Series的使用場景從一維拓展到多維。DataFrame既有行索引,也有列索引。
- 行索引:index
- 列索引:columns
- 值:values
創建 Pandas DataFrame
第一步:創建 Pandas Series 字典
第二步:將字典傳遞給 pd.DataFrame
1 items = {'Bob': pd.Series(data=[245, 25, 55], index=['bike', 'pants', 'watch']), 2 'Alice': pd.Series(data=[40, 110, 500, 45], index=['book', 'glasses', 'bike', 'pants'])} 3 shopping_carts = pd.DataFrame(items) 4 print(shopping_carts)
通過關鍵字 columns 和 index 選擇要將哪些數據放入 DataFrame 中
1 shopping_cart = pd.DataFrame(items, index=['bike', 'pants'], columns=['Bob']) 2 print(shopping_cart)
訪問整列:dataframe[['column1', 'column2']]
1 # 讀取列 2 print(shopping_carts[['Bob', 'Alice']])
訪問整行:dataframe.loc[['row1', 'row2']]
# 讀取行 print(shopping_carts.loc[['bike']])
訪問某行某列:dataframe['column']['row'],先提供行標簽,將出錯。
# 讀取某一列某一行 print(shopping_carts['Bob']['bike'])
【注意】 直接用中括號時:
- 索引表示的是列索引
- 切片表示的是行切片
shopping_carts[0:2] #讀取第一二行的數據
添加整列(末尾添加列),空值用 None
# 添加列 shopping_carts['Mike'] = [10, 30, 10, 90, None]
添加整行(末尾添加行),把新添加行創建為 dataframe,通過 append() 添加
# 添加行 new_items = [{'Alice': 30, 'Bob': 20, 'Mark': 35, 'Mike': 50}] new_store = pd.DataFrame(new_items, index=['store3']) shopping_carts = shopping_carts.append(new_store)
只能刪除整列:pop('lable')
# 刪除整列 shopping_carts.pop('Jey')
刪除行或者列:drop(['lable1', 'lable2'], axis=0/1) 0表示行,1表示列
# 刪除行 shopping_carts = shopping_carts.drop(['store3', 'watch'], axis=0)
更改行和列標簽
rename()
# 更改列標簽 shopping_carts = shopping_carts.rename(columns={'Bob': 'Jey'}) # 更改行標簽 shopping_carts = shopping_carts.rename(index={'bike': 'hats'})
處理 NaN
統計 NaN 數量:isnull().sum().sum
# 數值轉化為 True 或者 False print(store_items.isnull()) # 每一列的 NaN 的數量 print(store_items.isnull().sum()) # NaN 總數 print(store_items.isnull().sum().sum())
統計非 NaN 數量:count(axis=0/1)
# 每一行非 NaN 的數量,通過列統計 print(store_items.count(axis=1)) # 每一列非 NaN 的數量,通過行統計 print(store_items.count(axis=0))
刪除具有NaN值的行和列:dropna(axis=0/1, inplace=True/False) inplace默認False,原始DataFrame不會改變;inplace為True,在原始DataFrame刪除行或者列
# 刪除包含NaN值的任何行 store_items.dropna(axis=0)
# 刪除包含NaN值的任何列 store_items.dropna(axis=1, inplace=True)
將 NaN 替換合適的值:fillna()
# 將所有 NaN 替換為 0 store_items.fillna(value=0) # 前向填充:將 NaN 值替換為 DataFrame 中的上個值,axis決定列或行中的上個值 store_items.fillna(method='ffill', axis=1) # 后向填充:將 NaN 值替換為 DataFrame 中的下個值,axis決定列或行中的下個值 store_items.fillna(method='backfill', axis=0)
pandas的拼接操作
- 級聯:pd.concat, pd.append
- 合並:pd.merge, pd.join
級聯
1,匹配級聯:
import numpy as np import pandas as pd from pandas import Series,DataFrame df1 = DataFrame(data=np.random.randint(0,100,size=(3,3)),index=['a','b','c'],columns=['A','B','C']) df2 = DataFrame(data=np.random.randint(0,100,size=(3,3)),index=['a','d','c'],columns=['A','d','C']) pd.concat((df1,df1),axis=0,join='inner')
2, 不匹配級聯
不匹配指的是級聯的維度的索引不一致。例如縱向級聯時列索引不一致,橫向級聯時行索引不一致
有2種連接方式:
- 外連接:補NaN(默認模式)
- 內連接:只連接匹配的項
pd.concat((df1,df2),axis=1,join='outer')
pd.merge()合並
merge與concat的區別在於,merge需要依據某一共同的列來進行合並
使用pd.merge()合並時,會自動根據兩者相同column名稱的那一列,作為key來進行合並。
注意每一列元素的順序不要求一致
參數:
- how:out取並集 inner取交集
- on:當有多列相同的時候,可以使用on來指定使用那一列進行合並,on的值為一個列表
1) 一對一合並
df1 = DataFrame({'employee':['Bob','Jake','Lisa'], 'group':['Accounting','Engineering','Engineering'], }) df1
df2 = DataFrame({'employee':['Lisa','Bob','Jake'], 'hire_date':[2004,2008,2012], }) df2
pd.merge(df1,df2,how='outer')
2) 多對一合並
df3 = DataFrame({ 'employee':['Lisa','Jake'], 'group':['Accounting','Engineering'], 'hire_date':[2004,2016]}) df3
df4 = DataFrame({'group':['Accounting','Engineering','Engineering'], 'supervisor':['Carly','Guido','Steve'] }) df4
pd.merge(df3,df4)
3) 多對多合並
df1 = DataFrame({'employee':['Bob','Jake','Lisa'], 'group':['Accounting','Engineering','Engineering']}) df1
df5 = DataFrame({'group':['Engineering','Engineering','HR'], 'supervisor':['Carly','Guido','Steve'] }) df5
pd.merge(df1,df5,how='outer')
4) key的規范化
- 當列沖突時,即有多個列名稱相同時,需要使用on=來指定哪一個列作為key,配合suffixes指定沖突列名
df1 = DataFrame({'employee':['Jack',"Summer","Steve"], 'group':['Accounting','Finance','Marketing']}) df2 = DataFrame({'employee':['Jack','Bob',"Jake"], 'hire_date':[2003,2009,2012], 'group':['Accounting','sell','ceo']}) display(df1,df2)
- 當兩張表沒有可進行連接的列時,可使用left_on和right_on手動指定merge中左右兩邊的哪一列列作為連接的列
加載數據
csv 格式文件,每一行都是用逗號隔開:read_csv()
1 # 讀取 csv 文件,第一行作為列標簽 2 data = pd.read_csv('data.csv') 3 print(data) 4 print(data.shape) 5 print(type(data))
讀取前 N 行數據:head(N)
# 讀取頭 3 行數據 print(data.head(3))
讀取最后 N 行數據:tail(N)
# 讀取后 5 行數據 print(data.tail(5))
檢查是否有任何列包含 NaN 值:isnull().any() / notnull().all() 類型 bool
# 檢查任何列是否有 NaN 值,返回值:bool print(data.isnull().any())
# 檢查任何行是否不存在 NaN 值,返回值:bool
data.notnull().all(axis=1)
數據集的統計信息:describe()
1 # 獲取 DataFrame 每列的統計信息:count,mean,std,min,25%,50%,75%,max 2 # 25%:四分之一位數;50%:中位數;75%:四分之三位數 3 print(data.describe()) 4 # 通過統計學函數查看某個統計信息 5 print(data.max()) 6 print(data.median())
數據相關性:不同列的數據是否有關聯,1 表明關聯性很高,0 表明數據不相關。corr()
1 # 數據相關性 2 print(data.corr())
數據分組:groupby(['lable1', 'lable2'])
1 # 按年份分組,統計總薪資 2 data.groupby(['Year'])['Salary'].sum() 3 # 按年份分組,統計平均薪資 4 data.groupby(['Year'])['Salary'].mean() 5 # 按年份,部門分組,統計總薪資 6 data.groupby(['Year', 'Department'])['Salary'].sum()
簡單練習
df = DataFrame(data=np.random.randint(10,50,size=(8,8))) df
df.iloc[1,2] = None df.iloc[2,2] = None df.iloc[6,2] = None df.iloc[6,7] = None df
df.loc[df.isnull().any(axis=1)] # 獲取所有存在空值的行
df.loc[df.notnull().all(axis=1)] # 檢測所有都不為空的行
df.dropna(axis=0) # 刪除存在所有存在空值的行