【问题标题】:Pandas df: group, bin and average in different columns?Pandas df:不同列中的组、bin和平均值?
【发布时间】:2020-04-01 22:02:23
【问题描述】:

我的数据在质量上看起来像这个虚拟表:

speed_observation, car_brand, traction_force
10, ford, 2
20, ford, 4
35, seat, 8
50, ford, 16
10, audi, 2
20, audi, 5
43, audi, 2
12, seat, 2.5
10, ford, 0.5
30, audi, 6
23, ford, 4
17, seat, 5.5
10, seat, 10
38, audi, 2
40, ford, 9
19, ford, 6.6
49, seat, 18
18, ford, 4 

我想按汽车品牌对数据框进行分组,并为每个品牌将速度观察结果分类为范围(例如 [0,25] 和 [25,50]),然后为每个品牌和分类计算平均牵引力测量,收到类似的东西:

speed_bin_upper_lim, car_brand, avrg_traction_force_in_speed_bin
25, audi, X1
50, audi, X2
25, ford, X3
50, ford, X4
25, seat, X5
50, seat, X6

我该怎么做?它应该适用于任意数量的唯一car_brand 类,并且用户应该只提供速度箱的数量或箱的范围(例如n=3[0,25,50])。我想pd.groupbypd.cut 会这样做,但我没有找到具体方法。


Quang Hoang 的回答效果很好,如果你想扩展它,因为你想再按一列分组,比如说wheel_kind,你的数据框看起来像:

speed_observation,car_brand,wheel_kind,traction_force
10, ford, winter, 2
20, ford, summer, 4
35, seat, summer, 8
50, ford, winter, 16
10, audi, summer, 2
20, audi, summer, 5
43, audi, summer, 2
12, seat, summer, 2.5
10, ford, summer, 0.5
30, audi, summer, 6
23, ford, summer, 4
17, seat, summer, 5.5
10, seat, summer, 10
38, audi, summer, 2
40, ford, summer, 9
19, ford, summer, 6.6
49, seat, summer, 18
18, ford, summer, 4

然后将wheel_kind 列添加到之前的解决方案中,更准确地说:

(df.groupby(['car_brand', `wheel_kind`, cuts])
   .traction_force.mean()
   .reset_index(name='avg_traction_force')
)

之后不要忘记删除 NaN,因为 fordaudi 没有冬季车轮:

df_grp.dropna(inplace=True)
df_grp.reset_index(drop=True, inplace=True) #just to reset the index

【问题讨论】:

    标签: python pandas dataframe pandas-groupby binning


    【解决方案1】:

    您可以将 speed_observation 剪切到所需的垃圾箱并按此分组:

    cuts = pd.cut(df['speed_observation'], [0,25,50])
    
    (df.groupby(['car_brand', cuts])
       .traction_force.mean()
       .reset_index(name='avg_traction_force')
    )
    

    输出:

      car_brand speed_observation  avg_traction_force
    0      audi           (0, 25]            3.500000
    1      audi          (25, 50]            3.333333
    2      ford           (0, 25]            3.516667
    3      ford          (25, 50]           12.500000
    4      seat           (0, 25]            6.000000
    5      seat          (25, 50]           13.000000
    

    【讨论】:

    • 太棒了!对于阅读本文的其他用户,我发现这做同样的事情,只是语法略有不同(df0.groupby(['car_brand', cuts]) .agg({'traction_force':'mean'}) .reset_index())
    【解决方案2】:

    我们可以 创建一个系列以手动分组以替代pd.cut

    n = 25
    
    blocks = (df.speed_observation.sub(1) // n).add(1).mul(n)
    blocks = blocks.rename('speed_bin_upper_lim') 
    
    (df.groupby([blocks, 'car_brand'])
       .traction_force.mean()
       .reset_index(name='avrg_traction_force_in_speed_bin'))
    
       speed_bin_upper_lim car_brand  avrg_traction_force_in_speed_bin
    0                   25      audi                          3.500000
    1                   25      ford                          3.516667
    2                   25      seat                          6.000000
    3                   50      audi                          3.333333
    4                   50      ford                         12.500000
    5                   50      seat                         13.000000
    

    详情

    print(blocks)
    0     25
    1     25
    2     50
    3     50
    4     25
    5     25
    6     50
    7     25
    8     25
    9     50
    10    25
    11    25
    12    25
    13    50
    14    50
    15    25
    16    50
    17    25
    Name: speed_bin_upper_lim, dtype: int64
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-23
      • 2018-11-20
      • 1970-01-01
      • 1970-01-01
      • 2016-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多