本文轉載自【微信公眾號:五角錢的程式設計師,ID:xianglin965】經微信公眾號授權轉載,如需轉載與原文作者聯繫
文章目錄
第4章 變形一、透視表1. pivot2. pivot_table3. crosstab(交叉表)二、其他變形方法1. melt2. 壓縮與展開三、啞變量與因子化1. Dummy Variable(啞變量)2. factorize方法第4章 變形
import numpy as npimport pandas as pddf = pd.read_csv('data/table.csv')df
一、透視表
1. pivot
一般狀態下,數據在DataFrame會以壓縮(stacked)狀態存放,例如上面的Gender,兩個類別被疊在一列中,pivot函數可將某一列作為新的cols:
df.pivot(index='ID',columns='Gender',values='Height').head()
然而pivot函數具有很強的局限性,除了功能上較少之外,還不允許values中出現重複的行列索引對(pair),例如下面的語句就會報錯:
# df.pivot(index='School',columns='Gender',values='Height').head()
因此,更多的時候會選擇使用強大的pivot_table函數
2. pivot_table
首先,再現上面的操作:
pd.pivot_table(df,index='ID',columns='Gender',values='Height').head()
由於功能更多,速度上自然是比不上原來的pivot函數:
%timeit df.pivot(index='ID',columns='Gender',values='Height')%timeit pd.pivot_table(df,index='ID',columns='Gender',values='Height')
Pandas中提供了各種選項,下面介紹常用參數:
① aggfunc:對組內進行聚合統計,可傳入各類函數,默認為’mean』
pd.pivot_table(df,index='School',columns='Gender',values='Height',aggfunc=['mean','sum']).head()
②margins:匯總邊際狀態
pd.pivot_table(df,index='School',columns='Gender',values='Height',aggfunc=['mean','sum'],margins=True).head()#margins_name可以設置名字,默認為'All
③ 行、列、值都可以為多級
pd.pivot_table(df,index=['School','Class'],columns=['Gender','Address'], values=['Height','Weight'])
3. crosstab(交叉表)
交叉表是一種特殊的透視表,典型的用途如分組統計,如現在想要統計關於街道和性別分組的頻數:
pd.crosstab(index=df['Address'],columns=df['Gender'])
交叉表的功能也很強大(但目前還不支持多級分組),下面說明一些重要參數:
① values和aggfunc:分組對某些數據進行聚合操作,這兩個參數必須成對出現
pd.crosstab(index=df['Address'],columns=df['Gender'],values=np.random.randint(1,20,df.shape[0]),aggfunc='min')#默認參數等於如下方法:#pd.crosstab(index=df['Address'],columns=df['Gender'],values=1,aggfunc='count')
②除了邊際參數margins外,還引入了normalize參數,可選』all』,『index』,'columns』參數值
pd.crosstab(index=df['Address'],columns=df['Gender'],normalize='all',margins=True)
二、其他變形方法
1. melt
melt函數可以認為是pivot函數的逆操作,將unstacked狀態的數據,壓縮成stacked,使「寬」的DataFrame變「窄」
df_m = df[['ID','Gender','Math']]df_m.head()
df.pivot(index='ID',columns='Gender',values='Math').head()
melt函數中的id_vars表示需要保留的列,value_vars表示需要stack的一組列
pivoted = df.pivot(index='ID',columns='Gender',values='Math')result = pivoted.reset_index().melt(id_vars=['ID'],value_vars=['F','M'],value_name='Math')\.dropna().set_index('ID').sort_index()#檢驗是否與展開前的df相同,可以分別將這些鏈式方法的中間步驟展開,看看是什麼結果result.equals(df_m.set_index('ID'))# result
2. 壓縮與展開
(1)stack:這是最基礎的變形函數,總共只有兩個參數:level和dropna
df_s = pd.pivot_table(df,index=['Class','ID'],columns='Gender',values=['Height','Weight'])df_s.groupby('Class').head(2)
df_stacked = df_s.stack()df_stacked.groupby('Class').head(2)
stack函數可以看做將橫向的索引放到縱向,因此功能類似與melt,參數level可指定變化的列索引是哪一層(或哪幾層,需要列表)
df_stacked = df_s.stack(0)df_stacked.groupby('Class').head(2)
(2)unstack:stack的逆函數,功能上類似於pivot_table
df_stacked.head()
result = df_stacked.unstack().swaplevel(1,0,axis=1).sort_index(axis=1)result.equals(df_s)#同樣在unstack中可以指定level參數
三、啞變量與因子化
1. Dummy Variable(啞變量)
這裡主要介紹get_dummies函數,其功能主要是進行one-hot編碼:
df_d = df[['Class','Gender','Weight']]df_d.head()
pd.get_dummies(df_d[['Class','Gender']]).join(df_d['Weight']).head()#可選prefix參數添加前綴,prefix_sep添加分隔符
2. factorize方法
該方法主要用於自然數編碼,並且缺失值會被記做-1,其中sort參數表示是否排序後賦值
codes, uniques = pd.factorize(['b', None, 'a', 'c', 'b'], sort=True)display(codes)display(uniques)