簡體   English   中英

如何在Pandas groupby對象中過濾1個值並使用它來計算新列?

[英]How to filter in a Pandas groupby object for 1 value and use it to calculate a new column?

我目前正在使用這樣的DataFrame(df):

df = pd.DataFrame({'fc_group': ['A', 'A', 'A','B', 'B', 'B', 'B', 'A', 'A', 'B','B'], 
                    'dt': ['2015-05-08', '2015-05-08', '2015-05-08', '2015-05-08', 
                           '2015-05-08', '2015-05-08', '2015-05-08', '2015-05-09', 
                           '2015-05-09', '2015-05-09', '2015-05-09'], 
                    'day': [0,1,2,0,1,2,3,1,2,0,1],
                    'value' : [50,150,200,60,170,220,378,140,240,700,1700]})

   fc_group          dt  day  value
0         A  2015-05-08    0     50
1         A  2015-05-08    1    150
2         A  2015-05-08    2    200
3         B  2015-05-08    0     60
4         B  2015-05-08    1    170
5         B  2015-05-08    2    220
6         B  2015-05-08    3    378
7         A  2015-05-09    1    140
8         A  2015-05-09    2    240
9         B  2015-05-09    0    700
10        B  2015-05-09    1   1700

我想通過“ fc_group”和“ dt”對它進行分組,並創建一個名為“ new_column”的新列,該列由

df [value] / df [df [day] == 0] [value]

要么

np.nan如果組中沒有第0天行。

結果應如下所示(我突出顯示了結果組)

   fc_group          dt  day  value  new_column
0         A  2015-05-08    0     50        1.00
1         A  2015-05-08    1    150        3.00
2         A  2015-05-08    2    200        4.00

3         B  2015-05-08    0     60        1.00
4         B  2015-05-08    1    170        2.83
5         B  2015-05-08    2    220        3.67
6         B  2015-05-08    3    378        6.30

7         A  2015-05-09    1    140        NaN
8         A  2015-05-09    2    240        NaN

9         B  2015-05-09    0    700        1.00
10        B  2015-05-09    1   1700        2.43

是否有一種時尚的pythonic方法來實現這一目標? 是由.apply調用的自定義函數,還是lambda函數? 我已經嘗試了幾種方法,但是似乎都沒有用(例如,使用lambda函數時,我無法獲得第0天的一個特定值,而使用海關函數並應用時,出現“不兼容索引”錯誤)

我發現的唯一可行的解​​決方案是創建一個groupby對象,然后使用for循環手動遍歷每個組,執行列創建,然后重新組合所有子組。 這相當慢,而且效率極低。 謝謝您的幫助 :)

首先使用boolean indexing通過eq僅過濾0值,然后與左連接merge並除以div

new = df[df['day'].eq(0)].rename(columns={'value':'new'})
#if possible multiple `0` values per columns 'fc_group','dt' get first rows only
#new = df[df['day'].eq(0)].drop_duplicates(subset=['fc_group','dt']).rename(columns={'value':'new'})
df['new'] = df['value'].div(df.merge(new, how='left', on=['fc_group','dt'])['new'])
print (df)
   fc_group          dt  day  value       new
0         A  2015-05-08    0     50  1.000000
1         A  2015-05-08    1    150  3.000000
2         A  2015-05-08    2    200  4.000000
3         B  2015-05-08    0     60  1.000000
4         B  2015-05-08    1    170  2.833333
5         B  2015-05-08    2    220  3.666667
6         B  2015-05-08    3    378  6.300000
7         A  2015-05-09    1    140       NaN
8         A  2015-05-09    2    240       NaN
9         B  2015-05-09    0    700  1.000000
10        B  2015-05-09    1   1700  2.428571

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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