本篇文章著重介紹一下分組統計的進階用法:
第一部分:分組:
根據現有的列去分組
這也是最簡單的,可以根據一個鍵,也可以傳入列表支持多個鍵:
創建數據:
df = pd.DataFrame({'A': ['a', 'b', 'a', 'c', 'a', 'c', 'b', 'c'],
'B': [2, 8, 1, 4, 3, 2, 5, 9],
'C': [102, 98, 107, 104, 115, 87, 92, 123]})
df
根據一個鍵:
df.groupby("A").sum()
根據兩個鍵:
df.groupby(["A","B"]).sum()
根據字典映射去分組:
mapping={"A":1,"B":1,"C":2}
df.groupby(mapping,axis=1).sum()
mapping={0:1,1:1,2:2,3:2,4:1,5:1,6:1,7:1}
df.groupby(mapping).sum()
應為A列是文本,pandas自動剔除了
根據列表(字典的簡便寫法):
但是有一個前提:必須是提供行或者列相等長度的列表:
mapping=[1,1,4]
df.groupby(mapping,axis=1).sum()
字典可以不相等嗎?,可以,但是沒有映射的數據將不在統計範圍內:
mapping={0:1,1:1,2:2}
df.groupby(mapping).sum()
mapping={"A":1,"B":1}
df.groupby(mapping,axis=1).sum()
擴展:因為字典的映射關係,我們也可以用映射去篩選需要統計的數據去透視
根據自定義區間分組:
這裡用到了cut函數,後面我會詳細介紹這個函數
dd_2=pd.cut(df['B'], bins=2)
df.groupby(dd_2).sum()
如果我們有一些數據,這些數據是包含年齡的,就可以根據這個方法來區分不同年齡段,也可以區分不同的時間段,反正用著的時候挺好用的
根據函數去分組:
根據函數分組的原理就是根據返回值來分組,相同的返回值將會被分為一組:
默認傳給函數的是索引:
def f(x):
print(x)
return x
df.groupby(f).sum()
def f(x):
print(x)
return x>5
df.groupby(f).sum()
如果想用別的列應用函數:
def f(x):
print(x)
return pd.cut(x,bins=3)
df.groupby(f(df["C"])).sum()
第二部分:統計計算
pandas在分組後的統計計算中,有一些常用的經過優化的一些方法:
今天要講的是如何應用這些方法
第一個介紹的是agg(Aggregate):
Aggregate using one or more operations over the specified axis
使用指定軸上的一個或多個操作進行聚合
意思是說,在指定的軸上使用一個或多個聚合函數
df.groupby("A").agg({"B":np.sum,"C":np.mean})
df.groupby("A").agg({"B":[np.sum,np.mean],"C":np.mean})
df.groupby('A')['B'].agg({'mean':np.mean, 'standard deviation': np.std})
第二個介紹:apply最重要的一個函數
df.groupby('A').apply(lambda x: x['C']-x['B'])
df.groupby('A').apply(lambda x: (x['C']-x['B']).mean())
想要用好apply還要明白他的原理:
首先來看看是如何分組的,這次利用groupby的迭代器讀取分組的數據:
for a,b in df.groupby('A'):
print(a)
print(b)
自定義函數應用時傳入的就是每一個分組數據,你可以利用DataFrame的特性來篩選相應的列然後用來計算,具體能達到什麼效果完全看你的想法了
注意:當你在根據鍵分組後具體返回什麼也是靠你的自定義函數.
比如,我們分組後只返回B列的數據:
def f(x):
return x["B"]
df.groupby("A").apply(f)
返回B的平方:
def f(x):
return x["B"]**2
df.groupby("A").apply(f)
apply能達到的不僅僅這一點:
下面我們計算一下每個分組的B列最大值和最小值的差:
def f(x):
return max(x["B"])-min(x["B"])
df.groupby("A").apply(f)
下面我們統計每個分組的最後一行數據,這個要求在很多工具裡面是很難實現的
def f(x):
return x[-1:]
df.groupby("A").apply(f)
想要用好apply的核心就在於:分組後傳入apply自定義函數的就是每個分組的DataFrame,返回值就是按照你的自定義函數來的。
最後介紹的一個函數是transform()
前面進行聚合運算的時候,得到的結果是一個以分組名為 index 的結果對象。如果我們想使用原數組的 index 的話,就需要進行 merge 轉換。transform(func, args, *kwargs) 方法簡化了這個過程,它會把 func 參數應用到所有分組,然後把結果放置到原數組的 index 上(如果結果是一個標量,就進行廣播):
df.groupby("A")["B"].transform(np.sum)
自定義函數:
def f(x):
return max(x)-min(x)
df.groupby("A")["B"].transform(f)
總結:
agg:適用於常用的函數算法
apply:適合自定義,功能強大,需要編寫函數,注意返回值
transform:如果你不想改變原有index,就需要用它
閱讀更多 嘩啦圈的夢 的文章