代码之家  ›  专栏  ›  技术社区  ›  astro123

pandas groupby apply/transform操作以对每个组执行操作

  •  0
  • astro123  · 技术社区  · 7 年前

    我有一个这样的数据框:

    import numpy as np
    import pandas as pd
    
    df = pd.DataFrame({'year': [1990,1990,1992,1992,1992],
                      'value': [100,200,300,400,np.nan],
                      'rank': [2,1,2,1,3]})
    print(df)
       year  value  rank
    0  1990  100.0     2
    1  1990  200.0     1
    2  1992  300.0     2
    3  1992  400.0     1
    4  1992    NaN     3
    

    我正在努力做到这一点:

    # For year 1990, maximum value is 200, rank is 1 and also relative value is 1.
    
       year  value  rank  value_relative
    0  1990  100.0     2  0.5
    1  1990  200.0     1  1
    2  1992  300.0     2  0.75
    3  1992  400.0     1  1
    4  1992    NaN     3  NaN
    

    我的尝试:

    df['value_relative'] = df.groupby('year')['value'].transform(lambda x: x/x[x.rank == 1]['value'])
    

    我们如何计算每年的相对价值呢?

    2 回复  |  直到 7 年前
        1
  •  2
  •   BENY    7 年前

    IIUC使用 transform 具有 first 之后 sort_values

    df['value_relative']=df.value/df.sort_values('rank').groupby('year').value.transform('first')
    df
    Out[60]: 
       year  value  rank  value_relative
    0  1990  100.0     2            0.50
    1  1990  200.0     1            1.00
    2  1992  300.0     2            0.75
    3  1992  400.0     1            1.00
    4  1992    NaN     3             NaN
    

    或者就这么做 转型 max

    df['value_relative']=df.value/df.groupby('year').value.transform('max')
    

    另一种方法

    df.value/df.loc[df.groupby('year')['rank'].transform('idxmin'),'value'].values
    Out[64]: 
    0    0.50
    1    1.00
    2    0.75
    3    1.00
    4     NaN
    Name: value, dtype: float64
    

    如果你需要二等分母

    df.value/df.year.map(df.loc[df['rank']==2].set_index('year')['value'])
    

    这里的不同取决于您如何获得排名,如果是基于最大值,那么它们都应该返回相同的结果,但是如果这是一个与值列无关的给定排名,那么您应该使用 第一

        2
  •  1
  •   astro123    7 年前

    我喜欢并接受温家宝的回答,但我想给我2美分:

    最简单的方法是将值除以最大值,但我尝试使用名为rank的单独列来学习如何做到这一点:

    df.groupby('year')['value'].transform(lambda x: x/x.max())
    0    0.50
    1    1.00
    2    0.75
    3    1.00
    4     NaN
    

    秩=2的另一个简单方法:

    df.groupby('year')['value'].transform(lambda x: x/x.nlargest(2).iloc[-1])
    0    1.000000
    1    2.000000
    2    1.000000
    3    1.333333
    4         NaN
    

    注:温氏法:

    df.value/df.year.map(df.loc[df['rank']==2].set_index('year')['value'])
        0    1.000000
        1    2.000000
        2    1.000000
        3    1.333333
        4         NaN