給妹子講python-S02E19GroupBy實現分割、應用和組合

給妹子講python-S02E19GroupBy實現分割、應用和組合

來自專欄給妹子講python

微信公眾號: python數據科學家

【要點搶先看】

1.GroupBy的使用場景和使用方法2.GroupBy分割、應用和組合的操作內涵3.GroupBy對象的遍歷

今天這一集我們開始介紹Pandas中對數據進行處理的一個高逼格的方法:GroupBy。

【妹子說】別說的這麼厲害,我只問,這個是幹嘛滴

好,我舉一個使用場景吧,科學家用不同的測量方法,測出了行星的質量、距離、軌道周期等等,就如同下面的代碼所示:

import seaborn as snsplanets = sns.load_dataset(planets)print(planets.head()) method number orbital_period mass distance year0 Radial Velocity 1 269.300 7.10 77.40 20061 Radial Velocity 1 874.774 2.21 56.95 20082 Radial Velocity 1 763.000 2.60 19.84 20113 Radial Velocity 1 326.030 19.40 110.62 20074 Radial Velocity 1 516.220 10.50 119.47 2009

注意一下,這裡的seaborn庫是一個新的第三方庫,我們用它來獲取數據,我們在命令行下用pip3 install seaborn就能實現自動安裝。

好的,我問你,我要你對使用相同method測出來的distance進行求平均值,你要怎麼求?

【妹子說】額,莫不是就要用到你說的GroupBy?

對,我們來做個示範:

import seaborn as snsplanets = sns.load_dataset(planets)print(planets.groupby(method))<pandas.core.groupby.DataFrameGroupBy object at 0x00000000021DC3C8>

從結果中我們可以看出,我們試圖以method數據列中不同的方法作為分組的依據,返回的是一個DataFrameGroupBy對象,本質上可以理解為就是一個特殊的DataFrame對象。但是請注意,這個變數是沒辦法直接列印出來的,只是一個中間狀態量。

包括我們還可以利用DataFrame獲取列的方法對其進行操作:

import seaborn as snsplanets = sns.load_dataset(planets)print(planets.groupby(method)[orbital_period])<pandas.core.groupby.SeriesGroupBy object at 0x000000000CF3E550>

可以類比的是,他得到了一個SeriesGroupBy對象,也是一個中間變數。

回到前面提的問題,獲取了分組,如果我們想在此基礎上求各個不同方法測得的distance的平均值,就非常簡單了。

import seaborn as snsplanets = sns.load_dataset(planets)print(planets.groupby(method)[distance].mean())methodAstrometry 17.875000Eclipse Timing Variations 315.360000Imaging 67.715937Microlensing 4144.000000Orbital Brightness Modulation 1180.000000Pulsar Timing 1200.000000Pulsation Timing Variations NaNRadial Velocity 51.600208Transit 599.298080Transit Timing Variations 1104.333333Name: distance, dtype: float64

從這個計算的結果中,我們可以更直觀的理解題目中「GroupBy,分割、應用和組合」這句話的含義:

(1)首先對原始的DataFrame對象進行按組分割,得到一個中間變數DataFrameGroupBy

(2)每一個組包含了指定method的一組distance值,然後對這些組分別應用mean方法求平均值;

(3)最後把各組對應的平均值進行組合,形成最後的一個Series完整結果。

這裡可以使用的方法很廣,包含了一般的統計方法:求和、求均值、求中位數、方差、累和、最值等常用方法。

自然,describe方法也是可以在此使用的。

import seaborn as snsplanets = sns.load_dataset(planets)print(planets.groupby(method)[year].describe())method Astrometry count 2.000000 mean 2011.500000 std 2.121320 min 2010.000000 25% 2010.750000 50% 2011.500000 75% 2012.250000 max 2013.000000Eclipse Timing Variations count 9.000000 mean 2010.000000 std 1.414214 min 2008.000000 25% 2009.000000 50% 2010.000000 75% 2011.000000 max 2012.000000Imaging count 38.000000 mean 2009.131579 std 2.781901 min 2004.000000 25% 2008.000000 50% 2009.000000 75% 2011.000000 max 2013.000000Microlensing count 23.000000 mean 2009.782609 std 2.859697 min 2004.000000 25% 2008.000000 50% 2010.000000 ... Pulsation Timing Variations std NaN min 2007.000000 25% 2007.000000 50% 2007.000000 75% 2007.000000 max 2007.000000Radial Velocity count 553.000000 mean 2007.518987 std 4.249052 min 1989.000000 25% 2005.000000 50% 2009.000000 75% 2011.000000 max 2014.000000Transit count 397.000000 mean 2011.236776 std 2.077867 min 2002.000000 25% 2010.000000 50% 2012.000000 75% 2013.000000 max 2014.000000Transit Timing Variations count 4.000000 mean 2012.500000 std 1.290994 min 2011.000000 25% 2011.750000 50% 2012.500000 75% 2013.250000 max 2014.000000Name: year, dtype: float64

用一下我們之前講過的unstack方法將這個多重索引的Series對象轉換成DataFrame對象,可讀性更強:

import seaborn as snsplanets = sns.load_dataset(planets)print(planets.groupby(method)[year].describe().unstack()) count mean std min 25% method Astrometry 2.0 2011.500000 2.121320 2010.0 2010.75 Eclipse Timing Variations 9.0 2010.000000 1.414214 2008.0 2009.00 Imaging 38.0 2009.131579 2.781901 2004.0 2008.00 Microlensing 23.0 2009.782609 2.859697 2004.0 2008.00 Orbital Brightness Modulation 3.0 2011.666667 1.154701 2011.0 2011.00 Pulsar Timing 5.0 1998.400000 8.384510 1992.0 1992.00 Pulsation Timing Variations 1.0 2007.000000 NaN 2007.0 2007.00 Radial Velocity 553.0 2007.518987 4.249052 1989.0 2005.00 Transit 397.0 2011.236776 2.077867 2002.0 2010.00 Transit Timing Variations 4.0 2012.500000 1.290994 2011.0 2011.75 50% 75% max method Astrometry 2011.5 2012.25 2013.0 Eclipse Timing Variations 2010.0 2011.00 2012.0 Imaging 2009.0 2011.00 2013.0 Microlensing 2010.0 2012.00 2013.0 Orbital Brightness Modulation 2011.0 2012.00 2013.0 Pulsar Timing 1994.0 2003.00 2011.0 Pulsation Timing Variations 2007.0 2007.00 2007.0 Radial Velocity 2009.0 2011.00 2014.0 Transit 2012.0 2013.00 2014.0 Transit Timing Variations 2012.5 2013.25 2014.0

我們通過GroupBy方法獲得的DataFrameGroupBy對象可以直接按分組進行迭代,每一輪迭代返回的對象是一個二元元組,包括對應的分組組名和這個組對應的DataFrame片段。

import seaborn as snsplanets = sns.load_dataset(planets)for (method, group) in planets.groupby(method): print("{0} shape={1}".format(method, group.shape))Astrometry shape=(2, 6)Eclipse Timing Variations shape=(9, 6)Imaging shape=(38, 6)Microlensing shape=(23, 6)Orbital Brightness Modulation shape=(3, 6)Pulsar Timing shape=(5, 6)Pulsation Timing Variations shape=(1, 6)Radial Velocity shape=(553, 6)Transit shape=(397, 6)Transit Timing Variations shape=(4, 6)

補充對照的說一下,對SeriesGroupBy進行分組迭代,每一輪迭代返回的對象就應該是各組對應的Sereis類型片段。


推薦閱讀:

如何利用八爪魚,實現餐飲大數據(以辰智商圈秀為例)
首屆UBDC全域大數據峰會在京舉辦:全域數據概念受追捧
大數據平台中用到的演算法模型
閑聊
三組數據帶你了解知乎現狀

TAG:數據挖掘 | 大數據 | 產品經理 |