亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么在使用 DataFrameGroupBy.agg 時可以訪問傳遞給聚合函數的系列

為什么在使用 DataFrameGroupBy.agg 時可以訪問傳遞給聚合函數的系列

皈依舞 2021-10-10 16:45:14
我在玩弄我無法解釋的對象apply和agg方法時進行了觀察DataFrameGroupBy。介紹我理解以下代碼,但它作為問題的介紹可能很有用。我正在分組 DataFrame my_df   key col0 col10    1    A    B1    1    C    D2    2    E    F3    2    G    H按'key'列然后apply按函數def func(df):      return ''.join(df['col0'] + df['col1'])產生>>> my_df.groupby('key').apply(func)key1    ABCD2    EFGHdtype: object這按預期工作。我可以訪問列'col0','col1'因為func使用時傳遞給的“分組塊”apply是數據幀。題我不明白為什么KeyError在使用agg而不是apply使用相同的功能時會引發no 。>>> my_df.groupby('key').agg(func)                                          col0  col1key            1    ABCD  ABCD2    EFGH  EFGH據我了解,當使用aggthen 時,func會Series 為 的每一列的每個組傳遞一個my_df,因此df參數應該是類型Series,并且嘗試執行df['col0']并且df['col1']應該生成一個KeyError.為什么會agg產生結果?我的在哪里KeyError?研究我確認,df是Series不能被索引與df['col0']和df['col1']與調試。然而my_df.groupby('key').agg(func)神奇的作品。設置:from IPython.core.debugger import Pdbimport sysdef set_trace():    Pdb().set_trace(sys._getframe().f_back)def func(df):     set_trace()     return ''.join(df['col0'] + df['col1'])用法:>>> my_df.groupby('key').agg(func)> <ipython-input-258-9f34bde72bce>(9)func()      6       7 def func(df):      8      set_trace()----> 9      return ''.join(df['col0'] + df['col1'])     10 ipdb> type(df)<class 'pandas.core.series.Series'>ipdb> df0    A1    CName: col0, dtype: objectipdb> df['col0']*** KeyError: 'col0'ipdb> df['col1']*** KeyError: 'col1'
查看完整描述

2 回答

?
守候你守候我

TA貢獻1802條經驗 獲得超10個贊

它實際上確實引發了一個KeyError你可以在包裝訪問時看到的try/except:


In [23]: def func(df): 

    ...:     print(type(df))

    ...:     print(df)

    ...:     print()

    ...:     try:

    ...:         df['col0']

    ...:     except KeyError:

    ...:         print('[Error]')

    ...:     return ''.join(df['col0'] + df['col1'])

    ...: 

    ...:

In [24]: df.groupby('key').agg(func)

<class 'pandas.core.series.Series'>

0    A

1    C

Name: col0, dtype: object

[Error]


<class 'pandas.core.series.Series'>

0    A

1    C

Name: col0, dtype: object

[Error]


<class 'pandas.core.series.Series'>

0    A

1    C

Name: 1, dtype: object

[Error]


<class 'pandas.core.frame.DataFrame'>

   key col0 col1

0    1    A    B

1    1    C    D


<class 'pandas.core.frame.DataFrame'>

   key col0 col1

2    2    E    F

3    2    G    H

這KeyError似乎被調用函數排除在外,因此它被靜音。


檢查一些源代碼表明agg實際上調用了這個函數。從這里它首先進入這個函數,它返回Noneifarg是一個函數(這是我們的情況)。最后它會在這里的地方try / except Exception進行。


查看完整回答
反對 回復 2021-10-10
?
猛跑小豬

TA貢獻1858條經驗 獲得超8個贊

agg將整個 DataFrame 傳遞給func. 從文檔中,


func : 函數、字符串、字典或字符串/函數列表 用于聚合數據的函數。如果是函數,則必須在傳遞 DataFrame 或傳遞給DataFrame.apply.


我相信這意味著該函數實際上是由 調度的apply,已知它對整個 DataFrame 進行操作。


你可以print在里面通過一個簡單的調用來公開它func:


def func(df):

    print(type(df))

    return ''.join(df['col0'] + df['col1']) 

df.groupby('key').agg(func)

<class 'pandas.core.series.Series'>

<class 'pandas.core.series.Series'>

<class 'pandas.core.series.Series'>

<class 'pandas.core.frame.DataFrame'>

<class 'pandas.core.frame.DataFrame'>

Out[87]: 

     col0  col1

key            

1    ABCD  ABCD

2    EFGH  EFGH

所以它確實得到了兩個 DataFrame 調用。但它也有 3 個帶有 Series 參數的調用,我無法解釋為什么會這樣,也許是一個錯誤(我無法在任何地方看到它的記錄)。


好吧,仔細想想,這是我能想到的最好的辦法?,F在,agg不確定您的函數想要如何處理數據,因此它將嘗試兩種方法并使用首先作為系列工作的任何輸出。這似乎是一個實現細節,但 Series 是第一個用于傳入數據的方法。如果這不起作用,則回退是傳遞一個 DataFrame 并希望它成功。讓我看看我是否可以讓它在一個例子中工作......


from itertools import count

c = count(0)


def func(x):

    i = next(c)

    print(i, type(x))

    if i <3:

        return 'xyz'

    return ((df['col0'] + df['col1']).tolist())


df.groupby('key').agg(func)


0 <class 'pandas.core.series.Series'>

1 <class 'pandas.core.series.Series'>

2 <class 'pandas.core.series.Series'>

3 <class 'pandas.core.series.Series'>

Out[126]: 

    col0              col1

key                       

1    xyz               xyz

2    xyz  [AB, CD, EF, GH]

接下來,改變循環條件,我們有:


def func(x):

    i = next(c)

    print(i, type(x))

    if i in {0, 1}:

        return 'xyz'

    return ((x['col0'] + x['col1']).tolist())


df.groupby('key').agg(func)


0 <class 'pandas.core.series.Series'>

1 <class 'pandas.core.series.Series'>

2 <class 'pandas.core.series.Series'>

3 <class 'pandas.core.series.Series'>

4 <class 'pandas.core.series.Series'>

5 <class 'pandas.core.frame.DataFrame'>

6 <class 'pandas.core.frame.DataFrame'>

Out[157]: 

    col0 col1

key          

1     AB   CD

2     EF   GH

并且,更改i in {0, 1}為i in {0, 4},


0 <class 'pandas.core.series.Series'>

1 <class 'pandas.core.series.Series'>

2 <class 'pandas.core.series.Series'>

3 <class 'pandas.core.series.Series'>

4 <class 'pandas.core.frame.DataFrame'>

5 <class 'pandas.core.frame.DataFrame'>

Out[158]: 

    col0 col1

key          

1    xyz  xyz

2     EF   GH

請注意函數類型的數量如何根據每次返回的內容而變化。


查看完整回答
反對 回復 2021-10-10
  • 2 回答
  • 0 關注
  • 192 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號