簡體   English   中英

為什么 groupby 操作的行為不同

[英]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 像diffpct_change不是 agg,它會返回與原始 dataframe 相同index的值,對於countmeansum它們是 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 的聚合(如cumsumpct_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM