1. 創建多層行索引
(1) 隱式構造
-
最常見的方法是給DataFrame構造函數的index參數傳遞兩個或更多的數組:
index = [['一班', '一班', '一班', '二班', '二班', '二班'], ['張三', '李四', '王五', '趙六', '田七', '孫八']]
data = np.random.randint(0,150, size=(6,6))
df = DataFrame(data=data, index=index, columns=columns)
-
Series也可以創建多層索引
index = [['一班', '一班', '一班', '二班', '二班', '二班'], ['張三', '李四', '王五', '趙六', '田七', '孫八']] data = np.random.randint(0,150, size=6) s = Series(data=data, index=index)
(2) 顯示構造pd.MultiIndex
-
使用數組
index = pd.MultiIndex.from_arrays([['一班', '一班', '一班', '二班', '二班', '二班'], ['張三', '李四', '王五', '趙六', '田七', '孫八']]) columns = [['期中', '期中', '期中', '期末', '期末', '期末'], ['語文', '數學', '英語', '語文', '數學', '英語']] data = np.random.randint(0,150, size=(6,6)) df = DataFrame(data=data, index=index, columns=columns)
-
使用tuple
index = pd.MultiIndex.from_tuples([('一班', '張三'), ('一班', '李四'), ('一班', '王五'), ('二班', '趙六'), ('二班', '田七'), ('二班', '孫八')]) columns = [['期中', '期中', '期中', '期末', '期末', '期末'], ['語文', '數學', '英語', '語文', '數學', '英語']] data = np.random.randint(0,150, size=(6,6)) df = DataFrame(data=data, index=index, columns=columns)
-
使用product
最簡單,推薦使用 ,有條件限制
index = pd.MultiIndex.from_arrays([['一班', '一班', '一班', '二班', '二班', '二班'], ['張三', '李四', '王五', '趙六', '田七', '孫八']]) columns = pd.MultiIndex.from_product([['期中', '期末'], ['語文', '數學', '英語']]) data = np.random.randint(0,150, size=(6,6)) df = DataFrame(data=data, index=index, columns=columns)
2. 多層列索引
除了行索引index,列索引columns也能用同樣的方法創建多層索引
3. 多層索引對象的索引與切片操作
(1)Series的操作
【重要】對於Series來說,直接中括號[]與使用.loc()完全一樣,推薦使用中括號索引和切片
索引
s['一班','張三']
s.loc['一班'].loc['張三']
s.loc['一班', '張三'] # 推薦寫法
s.iloc[0] # 隱式索引, 直接從最內層開始索引,起始下標為0
s.iloc[[0]]
切片
s.loc['一班':]
s.iloc[0:4]
(2)DataFrame的操作
索引:
重要: 列索引使用[], 行索引需使用loc[]
注意在對行索引的時候,若一級行索引還有多個,對二級行索引會遇到問題!也就是說,無法直接對二級索引進行索引,必須讓二級索引變成一級索引后才能對其進行索引!
df['期中', '語文'] # 列索引
行多級索引的索引和切片操作
df.loc['一班', '張三']
切片:
df['一班': '二班']
df.loc['一班': ]
df.iloc[0:4] # 隱式行切片
4. 索引的堆(stack)
-
stack()
-
unstack()
把水平的列索引轉化為行索引就叫做stack 反之叫做unstack
df.stack() # 默認level=-1表示對最里面那一層操作
df.stack(level=0) # 對最外層操作
df.unstack(fill_value=0)
【小技巧】使用stack()的時候,level等於哪一個,哪一個就消失,出現在行里。
使用unstack()的時候,level等於哪一個,哪一個就消失,出現在列里。
5. 聚合操作
【注意】
-
需要指定axis
-
axis=0, 操作每一列,行數被壓縮
-
axis=1, 操作每一行,列數被壓縮
df.sum(axis=0, level=0) # level等於哪一層,哪一層就保留下來,其他層就被聚合掉.
二.pandas的拼接操作
pandas的拼接分為兩種:
-
級聯:pd.concat, pd.append
-
合並:pd.merge
1. 使用pd.concat()級聯
pandas使用pd.concat函數,與np.concatenate函數類似,只是多了一些參數:
numpy 級聯: concatenate pandas級聯: concat
1) 簡單級聯
和np.concatenate一樣,優先增加行數(默認axis=0)
pd.concat((df1,df2), ignore_index=True) # ignore_index 選擇忽略原索引,重新索引
pd.concat((df1,df2), keys=['df1', 'df2']) # keys 使用多層索引,默認axis=0
2) 不匹配級聯
不匹配指的是級聯的維度的索引不一致。例如縱向級聯時列索引不一致,橫向級聯時行索引不一致
有3種連接方式:
-
外連接:補NaN(默認模式)
pd.concat((df1, df2), sort=True, join='outer')
-
內連接:只連接匹配的項
pd.concat((df1, df2), sort=True, join='inner')
-
連接指定軸 join_axes
pd.concat((df1, df2), sort=True, join_axes=[df1.columns]) # 只保留df1的列
join_axes=[df1.columns] 相當於左連接
join_axes=[df2.columns] 相當於右連接
axis=1 指定水平方向級聯 還是垂直方向級聯 (默認垂直)
3) 使用append()函數添加
函數append專門用於在后面添加, 只能追加行
ddd.append(ddd2)
2. 使用pd.merge()合並
merge與concat的區別在於,merge需要依據某一共的列來進行合並
注意每一列元素的順序不要求一致
-
默認根據兩者相同column名稱的那一列作為key來進行合並
-
使用on指定哪一列為key,當有多個key相同時使用
pd.merge(df1, df2, on='name', suffixes=['df1', 'df2'])
-
兩邊的key都不相同時, 使用left_on和right_on指定左右兩邊的列作為key
pd.merge(df1, df2, left_on='name', right_on='名字')
-
當左邊的列和右邊的index相同的時候,使用left_on 和 right_index=True , 反之一樣
pd.merge(df1, df2, left_on='age', right_index=True)
內合並與外合並
-
內合並:只保留兩者都有的key對應的行(默認模式how='inner')
-
外合並 how='outer': 缺失補NaN
df1.merge(df2, left_on='name', right_on='名字', how='outer')
列沖突的解決
有多個列名稱相同時,需要使用on=來指定哪一個列作為key,配合suffixes指定沖突列名