![](/img/trans.png)
[英]Why does 'groupby(x, np.isnan)' behave differently to 'groupby(x) if key is nan'?
[英]Why does groupby operations behave differently
當使用pandas groupby 函數並在 groupby 之后操作 output 時,我注意到某些函數在作為索引返回的內容以及如何操作方面表現不同。
假設我們有一個 dataframe,其中包含以下信息:
Name Type ID
0 Book1 ebook 1
1 Book2 paper 2
2 Book3 paper 3
3 Book1 ebook 1
4 Book2 paper 2
如果我們這樣做
df.groupby(["Name", "Type"]).sum()
我們得到一個DataFrame
:
ID
Name Type
Book1 ebook 2
Book2 paper 4
Book3 paper 3
其中包含一個 MultiIndex,其中包含 groupby 中使用的列:
MultiIndex([('Book1', 'ebook'),
('Book2', 'paper'),
('Book3', 'paper')],
names=['Name', 'Type'])
和一列稱為ID
。
但如果我應用size()
function,結果是一個Series
:
Name Type
Book1 ebook 2
Book2 paper 2
Book3 paper 1
dtype: int64
最后,如果我執行pct_change()
,我們只會得到結果 DataFrame 列:
ID
0 NaN
1 NaN
2 NaN
3 0.0
4 0.0
長話短說;博士。 我想知道為什么有些函數返回一個Series
而有些函數返回一個DataFrame
,因為這讓我在處理同一個 DataFrame 中的不同操作時感到困惑。
從文件
尺碼:
Returns Series Number of rows in each group.
對於sum
,由於您沒有傳遞 sum 的列,因此它將返回沒有 groupby 鍵的數據框
df.groupby(["Name", "Type"])['ID'].sum() # return Series
Function 像diff
和pct_change
不是 agg,它會返回與原始 dataframe 相同index
的值,對於count
, mean
, sum
它們是 agg,返回值和groupby
鍵作為索引
輸出不同是因為聚合不同,而這些主要控制返回的內容。 想想數組等價物。 數據相同,但一個“聚合”返回單個標量值,另一個返回與輸入大小相同的數組
import numpy as np
np.array([1,2,3]).sum()
#6
np.array([1,2,3]).cumsum()
#array([1, 3, 6], dtype=int32)
DataFrameGroupBy object 的聚合也是如此groupby
所做的所有第一部分都是創建從 DataFrame 到組的映射。 因為這並沒有真正做任何事情,所以沒有理由為什么具有不同操作的相同 groupby 需要返回相同類型的 output(見上文)。
gp = df.groupby(["Name", "Type"])
# Haven't done any aggregations yet...
這里的另一個重要部分是我們有一個DataFrame GroupBy object。還有Series GroupBy 對象,這種差異可以改變返回值。
gp
#<pandas.core.groupby.generic.DataFrameGroupBy object>
那么聚合時會發生什么?
使用DataFrameGroupBy
,當您選擇聚合(如sum
)時,每組折疊為單個值,返回值將是 DataFrame,其中索引是唯一的分組鍵。 返回值是DataFrame
,因為我們提供了一個 DataFrameGroupBy object。DataFrame 可以有多個列,如果有另一個數字列,它也會聚合該列,因此需要 DataFrame output。
gp.sum()
# ID
#Name Type
#Book1 ebook 2
#Book2 paper 4
#Book3 paper 3
另一方面,如果您使用 SeriesGroupBy object(使用[]
選擇單個列),那么您將返回一個系列,同樣帶有唯一組鍵的索引。
df.groupby(["Name", "Type"])['ID'].sum()
|------- SeriesGroupBy ----------|
#Name Type
#Book1 ebook 2
#Book2 paper 4
#Book3 paper 3
#Name: ID, dtype: int64
對於返回 arrays 的聚合(如cumsum
、 pct_change
),DataFrameGroupBy 將返回 DataFrame,而 SeriesGroupBy 將返回一個系列。 但是索引不再是唯一的組鍵。 這是因為那沒有什么意義; 通常,您希望在組內進行計算,然后將結果分配回原始 DataFrame。因此,返回的索引與您為聚合提供的原始 DataFrame 一樣。 這使得創建這些列非常簡單,因為 pandas 處理所有 alignment
df['ID_pct_change'] = gp.pct_change()
# Name Type ID ID_pct_change
#0 Book1 ebook 1 NaN
#1 Book2 paper 2 NaN
#2 Book3 paper 3 NaN
#3 Book1 ebook 1 0.0 # Calculated from row 0 and aligned.
#4 Book2 paper 2 0.0
但是size
呢? 那個有點奇怪。 組的size
是一個標量。 該組有多少列或這些列中的值是否丟失並不重要,因此向其發送 DataFrameGroupBy 或 SeriesGroupBy object 是無關緊要的。 結果pandas
將始終返回一個Series
。 再次作為一個返回標量的組級聚合,讓返回值由唯一的組鍵索引是有意義的。
gp.size()
#Name Type
#Book1 ebook 2
#Book2 paper 2
#Book3 paper 1
#dtype: int64
最后為了完整起見,盡管像sum
這樣的聚合返回單個標量值,但將這些值帶回原始 DataFrame 中該組的每一行通常很有用。但是,正常.sum
的返回具有不同的索引,因此它不會對齊。 您可以將值merge
回唯一鍵,但pandas
提供了transform
這些聚合的能力。 由於此處的目的是將其恢復為原始 DataFrame,因此 Series/DataFrame 的索引與原始輸入相同
gp.transform('sum')
# ID
#0 2 # Row 0 is Book1 ebook which has a group sum of 2
#1 4
#2 3
#3 2 # Row 3 is also Book1 ebook which has a group sum of 2
#4 4
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.