使用 Pandas 更好地做資料科學(二)
之前分享過一篇 ofollow,noindex">使用Pandas更好的做資料科學 , 今天我們將學習pandas中的風騷操作:
-
df.resample: 重新取樣
-
df.agg: 聚合(對列進行聚合操作)
-
df.groupby: 分組
agg它提供基於 列的聚合操作 。而groupby可以看做是基於行的聚合操作。
從實現上看,groupby返回的是一個DataFrameGroupBy結構,這個結構必須呼叫聚合函式(如sum)之後,才會得到結構為Series的資料結果。
而agg是DataFrame的直接方法,返回的也是一個DataFrame。當然,很多功能用sum、mean等等也可以實現。但是agg更加簡潔, 而且傳給它的函式可以是字串,也可以自定義,引數是column對應的子DataFrame
import pandas as pd df = pd.read_excel("sample-salesv3.xlsx") #檢視前5行 df.head()
將將日期字串轉化為pandas裡的datetime類,這樣可以使用一些高階用法
#df.date = pd.to_datetime(df.date)該寫法與下面一行作用等同 df["date"] = pd.to_datetime(df['date']) df.head()
將date轉化為dataframe中的index,使用df.set_index(colname),這裡我們
df.set_index('date') #注意df.set_index('date', inplace=True)的區別
我們統計ext price在每個月的累和(sum)值。
(重點的resample、groupby和agg在廣告之後,親們可以點點廣告放鬆放鬆。精彩馬上就來)
df.resample
重新取樣,是對原樣本重新處理的一個方法,是一個對常規時間序列資料重新取樣和頻率轉換的便捷的方法。
-
注意:resample 只有在index為datetime型別(pandas的datetime型別)的時候才能用
-
resample()的引數為Y、M、D分別表示從年、月、日水平上從資料中抽樣
#每隔20天作為週期抽樣,計算每個週期內ext price的累積和 df.set_index('date').resample('20D')['account number'].sum()
執行結果
date 2014-01-01 07:21:5147757800 2014-01-21 07:21:5137163241 2014-02-10 07:21:5136028996 2014-03-02 07:21:5136124347 2014-03-22 07:21:5148225563 2014-04-11 07:21:5143983337 2014-05-01 07:21:5141839607 2014-05-21 07:21:5140654505 2014-06-10 07:21:5139456582 2014-06-30 07:21:5147094772 2014-07-20 07:21:5137634500 2014-08-09 07:21:5134500589 2014-08-29 07:21:5135385650 2014-09-18 07:21:5141619350 2014-10-08 07:21:5140574001 2014-10-28 07:21:5134540767 2014-11-17 07:21:5137910846 2014-12-07 07:21:5141859385 2014-12-27 07:21:516582924 Name: account number, dtype: int64
從上面的執行結果,我們看到日期大概是以20天為間隔,從資料集中抽樣。
#以月作為週期抽樣,計算每個週期內ext price的累積和 df.set_index('date').resample('M')['ext price'].sum()
執行結果
date 2014-01-31185361.66 2014-02-28146211.62 2014-03-31203921.38 2014-04-30174574.11 2014-05-31165418.55 2014-06-30174089.33 2014-07-31191662.11 2014-08-31153778.59 2014-09-30168443.17 2014-10-31171495.32 2014-11-30119961.22 2014-12-31163867.26 Freq: M, Name: ext price, dtype: float64
更進一步,我們想知道每個使用者每個月的sum值,那麼就需要一個groupby了:
df.groupby()-分組
df.set_index('date').groupby('name')['ext price'].resample("M").sum() #效果等同的程式碼 df.groupby(['name', pd.Grouper(key='date', freq='M')])['ext price'].sum()
執行結果
namedate Barton LLC2014-01-316177.57 2014-02-2812218.03 2014-03-313513.53 2014-04-3011474.20 2014-05-3110220.17 2014-06-3010463.73 2014-07-316750.48 2014-08-3117541.46 2014-09-3014053.61 2014-10-319351.68 2014-11-304901.14 2014-12-312772.90 Cronin, Oberbrunner and Spencer2014-01-311141.75 2014-02-2813976.26 2014-03-3111691.62 2014-04-303685.44 2014-05-316760.11 2014-06-305379.67 2014-07-316020.30 2014-08-315399.58 2014-09-3012693.74 2014-10-319324.37 2014-11-306021.11 2014-12-317640.60 Frami, Hills and Schmidt2014-01-315112.34 2014-02-284124.53 2014-03-3110397.44 2014-04-305036.18 2014-05-314097.87 2014-06-3013192.19 ... Trantow-Barrows2014-07-3111987.34 2014-08-3117251.65 2014-09-306992.48 2014-10-3110064.27 2014-11-306550.10 2014-12-3110124.23 White-Trantow2014-01-3113703.77 2014-02-2811783.98 2014-03-318583.05 2014-04-3019009.20 2014-05-315877.29 2014-06-3014791.32 2014-07-3110242.62 2014-08-3112287.21 2014-09-305315.16 2014-10-3119896.85 2014-11-309544.61 2014-12-314806.93 Will LLC2014-01-3120953.87 2014-02-2813613.06 2014-03-319838.93 2014-04-306094.94 2014-05-3111856.95 2014-06-302419.52 2014-07-3111017.54 2014-08-311439.82 2014-09-304345.99 2014-10-317085.33 2014-11-303210.44 2014-12-3112561.21 Name: ext price, Length: 240, dtype: float64
對比兩種寫法
#A寫法
df.set_index('date').groupby('name')['ext price'].resample("M").sum()
#B寫法
df.groupby(['name', pd.Grouper(key='date', freq='M')])['ext price'].sum()
顯然, B寫法 多敲了很多次鍵盤,那麼它的好處是啥呢?
-
首先,邏輯上更加直接,當你敲程式碼完成以上統計的時候,你首先想到的就是groupby操作,而set_index, resample好像不會立馬想到。
-
想到了groupby這個'動作'之後,你就會緊接著想按照哪個key來操作,此時你只需要用字串,或者Grouper把key定義好就行了。
-
最後使用聚合函式sum(),就得到了結果。
所以,從程式碼可讀性角度看, B寫法 更容易記憶。
df.agg
agg它提供基於 列的聚合操作 。而groupby可以看做是基於行的聚合操作。
從實現上看,groupby返回的是一個DataFrameGroupBy結構,這個結構必須呼叫聚合函式(如sum)之後,才會得到結構為Series的資料結果。
而agg是DataFrame的直接方法,返回的也是一個DataFrame。
當然,很多功能用sum、mean等等也可以實現。但是agg更加簡潔, 而且傳給它的函式可以是字串,也可以自定義,引數是column對應的子DataFrame
#df[["ext price", "quantity", "unit price"]]返回的是pd.DataFrame型別 #df["ext price", "quantity", "unit price"]返回的是pd.Series型別 df[["ext price", "quantity", "unit price"]].agg(['sum', 'mean'])
df.agg-針對不同的列使用不同的聚合函式
df.agg({'ext price': ['sum', 'mean'], 'quantity': ['sum', 'mean'], 'unit price': ['mean']})
往期文章
深度學習之 圖解LSTM
PyTorch實戰: 使用卷積神經網路對照片進行分類