數據分組
分組統計 - groupby功能
① 根據某些條件將數據拆分成組
② 對每個組獨立應用函數
③ 將結果合並到一個數據結構中
Dataframe在行(axis=0)或列(axis=1)上進行分組,將一個函數應用到各個分組並產生一個新值,然后函數執行結果被合並到最終的結果對象中。
df.groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, **kwargs)
注:因為輸出結果冗長,請讀者自行賦值粘貼到jupyter(推薦)中運行。歡迎評論交流
分組
df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar','foo', 'bar', 'foo', 'foo'], 'B' : ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], 'C' : np.random.randn(8), 'D' : np.random.randn(8)}) print(df) print('------') print(df.groupby('A'), type(df.groupby('A'))) print('------') # 直接分組得到一個groupby對象,是一個中間數據,沒有進行計算 a = df.groupby('A').mean() b = df.groupby(['A','B']).mean() c = df.groupby(['A'])['D'].mean() # 以A分組,算D的平均值 print("-----------------") print(a,type(a),'\n',a.columns) print() print(b,type(b),'\n',b.columns) print() print(c,type(c)) # 通過分組后的計算,得到一個新的dataframe # 默認axis = 0,以行來分組 # 可單個或多個([])列分組
#按A列分組求出A,B列的個數
grouped = df.groupby(["A"])
n = grouped.agg({"A": ["count", pd.Series.unique], "B": pd.Series.nunique})
print(n)
分組 - 可迭代對象
df = pd.DataFrame({'X' : ['A', 'B', 'A', 'B'], 'Y' : [1, 4, 3, 2]}) print(df) print(df.groupby('X'), type(df.groupby('X'))) print('-----') print(list(df.groupby('X')), '→ 可迭代對象,直接生成list\n') print(list(df.groupby('X'))[0], '→ 以元祖形式顯示\n') for n,g in df.groupby('X'): print(n) print(g) print('###') print('-----') # n是組名,g是分組后的Dataframe print(df.groupby(['X']).get_group('A'),'\n') print(df.groupby(['X']).get_group('B'),'\n') print('-----') # .get_group()提取分組后的組 grouped = df.groupby(['X']) print(grouped.groups) print(grouped.groups['A']) # 也可寫:df.groupby('X').groups['A'] print('-----') # .groups:將分組后的groups轉為dict # 可以字典索引方法來查看groups里的元素 sz = grouped.size() print(sz,type(sz)) print('-----') # .size():查看分組后的長度 df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar','foo', 'bar', 'foo', 'foo'], 'B' : ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'], 'C' : np.random.randn(8), 'D' : np.random.randn(8)}) print(df) print() print(df.groupby(['A','B'])) print() grouped = df.groupby(['A','B']).groups print(grouped) print() print(grouped[('foo', 'three')]) # 按照兩個列進行分組
其他軸上的分組
import pandas as pd import numpy as np df = pd.DataFrame({'data1':np.random.rand(2), 'data2':np.random.rand(2), 'key1':['a','b'], 'key2':['one','two']}) print(df) print(df.dtypes) print("-------------") print(df.groupby(df.dtypes, axis=1)) print('-----') print(list(df.groupby(df.dtypes, axis=1))) print() for n,p in df.groupby(df.dtypes, axis=1): print(n) print() print(p) print('##') # 按照值類型分列
通過字典或者Series分組
df = pd.DataFrame(np.arange(16).reshape(4,4), columns = ['a','b','c','d']) print(df) print('-----') mapping = {'a':'one','b':'one','c':'two','d':'two','e':'three'} by_column = df.groupby(mapping, axis = 1) print(by_column.sum()) print('-----') # mapping中,a、b列對應的為one,c、d列對應的為two,以字典來分組 s = pd.Series(mapping) print(s,'\n') print(s.groupby(s).count()) # s中,index中a、b對應的為one,c、d對應的為two,以Series來分組
通過函數分組
df = pd.DataFrame(np.arange(16).reshape(4,4), columns = ['a','b','c','d'], index = ['abc','bcd','aa','b']) print(df,'\n') print(df.groupby(len).sum()) # 按照字母長度分組
分組計算函數方法
s = pd.Series([1, 2, 3, 10, 20, 30], index = [1, 2, 3, 1, 2, 3]) grouped = s.groupby(level=0) # 唯一索引用.groupby(level=0),將同一個index的分為一組 print(grouped) print(grouped.first(),'→ first:非NaN的第一個值\n') print(grouped.last(),'→ last:非NaN的最后一個值\n') print(grouped.sum(),'→ sum:非NaN的和\n') print(grouped.mean(),'→ mean:非NaN的平均值\n') print(grouped.median(),'→ median:非NaN的算術中位數\n') print(grouped.count(),'→ count:非NaN的值\n') print(grouped.min(),'→ min、max:非NaN的最小值、最大值\n') print(grouped.std(),'→ std,var:非NaN的標准差和方差\n') print(grouped.prod(),'→ prod:非NaN的積\n')
多函數計算:agg()
df = pd.DataFrame({'a':[1,1,2,2], 'b':np.random.rand(4), 'c':np.random.rand(4), 'd':np.random.rand(4),}) print(df) print(df.groupby('a').agg(['mean',np.sum])) print(df.groupby('a')['b'].agg({'result1':np.mean, 'result2':np.sum})) # 函數寫法可以用str,或者np.方法 # 可以通過list,dict傳入,當用dict時,key名為columns
下面是一個測試題,大家可以嘗試一下
按要求創建Dataframe df(如下圖),並通過分組得到以下結果
① 以A分組,求出C,D的分組平均值
② 以A,B分組,求出D,E的分組求和
③ 以A分組,得到所有分組,以字典顯示
④ 按照數值類型分組,求和
⑤ 將C,D作為一組分出來,並計算求和
⑥ 以B分組,求出每組的均值,求和,最大值,最小值
import pandas as pd import numpy as np df = pd.DataFrame({"A":["one","two","three","one","two","three","one","two"], "B":(list("hhhh") + list("ffff")), "C":range(10,26,2), "D":np.random.randn(8), "E":np.random.rand(8) }) print(df) print("----------以A分組,求出CD的分組平均值-------------") print(df.groupby(["A"], axis = 0)["C","D"]) df1 = df.groupby(["A"], axis = 0)["C","D"].mean() # 先聚合 print(df1) print("-----------以AB分組,求DE的分組和--------") df2 = df.groupby(["A", "B"], axis = 0)["D","E"].sum() # 先聚合 print(df2) print("-----------以A分組,得到所有分組的字典--------") df2 = df.groupby(["A"], axis = 0) print(df2.groups) print("按照數值類型分組,求和") df3 = df.groupby(df.dtypes, axis = 1).sum() print(df3) print("----------將CD作為一組分出來,並計算求和-----------") mapping = {"C":"one", "D":"one"} print(df.groupby(mapping, axis = 1).sum()) print("------------以B分組,求每一組的均值、和、最大值、最小值-----------------------------------------------------") print(df.groupby(["B"]).agg([np.mean, np.sum, np.max, np.min]))