首先需要澄清的一點就是,excel非常強大,可視化的數據處理,強大的函數,內置power query,但是這些優點仍然沒有把小編留下,因為,最核心的一個功能,excel始終沒有跟上:
那就是數據分析
為什麼這麼說呢,excel在基礎的數據收集整理處理方面有著得天獨厚的優勢,但是我們收集數據要幹什麼,不就是要分析數據嗎,但是excel能夠提供的功能卻有些欠缺,比如:
經常用的數據透視表,能夠用的計算方式只有,求和,平均,最大,最小等,實際分析中,這些計算方式有些過於基礎,分組方式也過於單一
而pandas中的數據分組透視功能卻非常強大,可以任意分組,自定義分組,分組後的數據可以應用更自由的應用函數,自定義函數更是把分組功能應用到極致,一些看似很複雜的分析需求,變得異常簡單
![什麼功能讓python-pandas與excel徹底拉開了距離](http://p2.ttnews.xyz/loading.gif)
今天小編帶大家一起看一下pandas的分組統計功能:groupby:
![什麼功能讓python-pandas與excel徹底拉開了距離](http://p2.ttnews.xyz/loading.gif)
第一部分:分組:
分組鍵可以有多種形式,且類型不必相同:
·列表或數組,其長度與待分組的軸一樣。
·表示DataFrame某個列名的值。
·字典或Series,給出待分組軸上的值與分組名之間的對應關係。
·函數,用於處理軸索引或索引中的各個標籤。
注意,後三種都只是快捷方式而已,其最終目的仍然是產生一組用於拆分對象的值。
根據現有的列去分組
這也是最簡單的,可以根據一個鍵,也可以傳入列表支持多個鍵:
創建數據:
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,返回值就是按照你的自定義函數來的。
還可以用這些常用的方法:
pandas.DataFrame.groupby
DataFrame.groupby(self, by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, observed=False, **kwargs)[source]
by : mapping, function, label, or list of labels
用於確定groupby的組。 如果by是一個函數,則調用對象索引的每個值。 如果傳遞了dict或Series,則將使用Series或dict VALUES來確定組(系列的值首先對齊;請參閱.align()方法)。 如果傳遞了ndarray,則使用這些值來確定組。 標籤或標籤列表可以通過self中的列傳遞給組。 請注意,元組被解釋為(單個)鍵。
axis : {0 or ‘index’, 1 or ‘columns’}, default 0
按照行或列分割
level : int, level name, or sequence of such, default None
如果軸是MultiIndex(分層),則按特定級別或級別分組。
as_index : bool, default True
對於聚合輸出,返回以組標籤作為索引的對象。 僅與DataFrame輸入相關。 as_index = False實際上是“SQL風格”的分組輸出。
sort : bool, default True
對組鍵進行排序。 關閉它可以獲得更好的性能。 請注意,這不會影響每組內觀察的順序。 Groupby保留每個組中的行順序。
group_keys : bool, default True
調用apply時,將組鍵添加到索引以標識片段。
squeeze : bool, default False
如果可能,減少返回類型的維度,否則返回一致類型。
observed : bool, default False
**kwargs
Optional, only accepts keyword argument ‘mutated’ and is passed to groupby.
閱讀更多 嘩啦圈的夢 的文章