pandas groupby 使用指南

1. groupby技術

groupby 是pandas 中非常重要的一個函數, 主要用於數據聚合和分類計算. 其思想是“split-apply-combine”(拆分 - 應用 - 合併).


pandas之父對groupby技術的圖片實例

pandas groupby 的應用非常靈活, 但只要記住上面的核心思想-“split-apply-combine”, 就不難理解了. 我不太擅長解釋這類概念性的東西, 直接看例子吧.

2. 例子

美國有一個數據是關於職業調查的. 可以通過下面的鏈接下載.
數據.
數據很簡單, 稍微解釋一下.

user_id age gender  occupation  zip_code
1   24  M   technician  85711
2   53  F   other   94043
3   23  M   writer  32067
4   24  M   technician  43537
5   33  F   other   15213

user_id: id號
age: 年齡
gender: 性別
occupation: 職業
zip_code: 郵政編碼, 通過郵政編碼可獲取所在城市

假設你已經下載並導入了上面的數據; 或者不需要下載, 直接用下面的代碼讀取遠程的數據.

url = "https://raw.githubusercontent.com/justmarkham/DAT8/master/data/u.user"
df = pd.read_csv(url, sep="|")

那麼, 怎麼解決下面的問題呢?

  1. 如何找出每一種職業的平均年齡?並按照平均年齡從大到小排序?
  2. 分別找出男人和女人每種職業的人數?
  3. 更進一步, 如何找出男人和女人在不同職業的平均年齡?

如果能快速解決上面的三個問題, 說明初步掌握groupby. 使用pandas解決的方法可能有多種, 但是這裏使用groupby還是比較方便的.

問題1 : 如何找出每一種職業的平均年齡?並按照平均年齡從大到小排序?

# 問題1, 一行代碼即可搞定
df.groupby("occupation").age.mean().sort_values(ascending=False)
# output
occupation
retired          63.071429
doctor           43.571429
educator         42.010526
healthcare       41.562500
librarian        40.000000
administrator    38.746835
executive        38.718750
marketing        37.615385
lawyer           36.750000
engineer         36.388060
writer           36.311111
salesman         35.666667
scientist        35.548387
other            34.523810
technician       33.148148
programmer       33.121212
homemaker        32.571429
artist           31.392857
entertainment    29.222222
none             26.555556
student          22.081633
Name: age, dtype: float64

sort_value 是用來排序的. 主要看前面的 df.groupby("occupation").age.mean() , 還記得前面說的groupby的思想嗎, “split-apply-combine”(拆分 - 應用 - 合併).
首先df按照每一種occupation拆分成多個部分, 然後分別計算每種occupation的age的平均值.然後合併成一個Dataframe或者Series.
值得注意的是, groupby之後是一個對象, 知道應用一個函數之後纔會變成一個Series或者Dataframe.

type(df.groupby("occupation"))
# output
pandas.core.groupby.groupby.DataFrameGroupBy

問題2 : 分別找出男人和女人每種職業的人數?

df.groupby(['occupation','gender']).size()
# Output
occupation     gender
administrator  F          36
               M          43
artist         F          13
               M          15
doctor         M           7
educator       F          26
               M          69
...

與前例稍微不同的是, 這次按照兩個column, occupation和gender來進行group. 然後通過size計算每個職業指定性別的人數.

問題3 : 如何找出男人和女人在不同職業的平均年齡?

df.groupby(['occupation','gender']).age.mean()
# Output
occupation     gender
administrator  F         40.638889
               M         37.162791
artist         F         30.307692
               M         32.333333
doctor         M         43.571429
educator       F         39.115385
               M         43.101449
engineer       F         29.500000
               M         36.600000
...

groupby 詳解

通過上面的例子, groupby 的基本應用應該已經講清, 總而言之記住核心思想. 接下來詳細的聊聊groupby的各種應用及細節.
首先來看看官方文檔的參數描述.

DataFrame.groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, observed=False, **kwargs)

最常用的參數其實只有兩個, by 跟 as_index, 其他的很少用到, 如果有需要用到的那就仔細閱讀官方文檔

by 就是我們上面用的, 可以是column, 但其實也可以是與df同行的Series.
as_index 是指是否將groupby的column作爲index, 默認是True

對groupby對象應用自定義函數

上面我們都是以pandas自帶的函數應用再group對象上的, 可不可以使用自定義的函數呢? 答案是可以的.先看下面的代碼

demo = df[:5]
demo.groupby("gender").apply(lambda x: print(x))
# output
   user_id  age gender occupation zip_code
1        2   53      F      other    94043
4        5   33      F      other    15213
   user_id  age gender occupation zip_code
1        2   53      F      other    94043
4        5   33      F      other    15213
   user_id  age gender  occupation zip_code
0        1   24      M  technician    85711
2        3   23      M      writer    32067
3        4   24      M  technician    43537

也就是說, 其實groupby之後的dataframe是按照不同的值區分的. 這樣我們就可以直接自定義函數來處理了. 如果你細心的話, 你會發現其中一個dataframe出現了兩次, 這是apply 的設計問題.詳情請看這裏:https://stackoverflow.com/questions/21390035/python-pandas-groupby-object-apply-method-duplicates-first-group
未完待續...

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章