Pandas将给定分组的NaN值替换为均值

4
我有一个大型数据集,格式如下:

    period_id  gic_subindustry_id  operating_mgn_fym5  operating_mgn_fym4  317        201509            25101010           13.348150           11.745965   
682        201509            20101010           10.228725           10.473917   
903        201509            20101010           NaN                 17.700966   
1057       201509            50101010           27.858305           28.378040   
1222       201509            25502020           15.598956           11.658813   
2195       201508            25502020           27.688324           22.969760   
2439       201508            45202020           NaN                 27.145216   
2946       201508            45102020           17.956425           18.327724 

实际上,我有每年数千个值,追溯至25年前,以及多个(10+)列。
我试图用该时间段的gic_industry_id中位数/平均值替换NaN值。
我尝试了以下操作:
df.fillna(df.groupby('period_id','gic_subindustry_id').transform('mean')),
但这似乎非常缓慢(几分钟后我停止了它)。
我意识到它可能很慢的原因是由于重新计算每个NaN的平均值。为了解决这个问题,我认为在每个period_id计算平均值,然后使用此平均值替换/映射每个NaN可能会更快。
means = df.groupby(['period_id', 'gic_subindustry_id']).apply(lambda x:x.mean())

输出:

                             operating_mgn_fym5  operating_mgn_fym4 operating_mgn_fym3 operating_mgn_fym2   
period_id gic_subindustry_id                                             
201509    45202030            1.622685  0.754661   0.755324  321.295665  
          45203010            1.447686  0.226571   0.334280   12.564398  
          45203015            0.733524  0.257581   0.345450   27.659407  
          45203020            1.322349  0.655481   0.468740   19.823722  
          45203030            1.461916  1.181407   1.487330   16.598534  
          45301010            2.074954  0.981030   0.841125   29.423161  
          45301020            2.621158  1.235087   1.550252   82.717147  

实际上,这个方法速度更快(30-60秒)。

然而,我还在苦苦思考如何将NaN映射到这些均值。而且,这是否是执行此映射的“正确”方式?速度实际上并不是最重要的,但如果能少于60秒就好了。

2个回答

5

如果数据框架具有相同的结构(由as_index=False给出),您可以使用群组依据的结果来使用fillna

df.fillna(df.groupby(['period_id', 'gic_subindustry_id'], as_index=False).mean())

#In [60]: df
#Out[60]: 
#   period_id  gic_subindustry_id  operating_mgn_fym5  operating_mgn_fym4
#0     201508            25502020           27.688324           22.969760
#1     201508            45102020           17.956425           18.327724
#2     201508            45202020                 NaN           27.145216
#3     201509            20101010           10.228725           14.087442
#4     201509            25101010           13.348150           11.745965
#5     201509            25502020           15.598956           11.658813
#6     201509            50101010           27.858305           28.378040
#7     201508            45102020           17.956425           18.327724

-1

我想下面的代码是正确的。

b = a.fillna(a.groupby(['period_id', 'gic_subindustry_id']).transform("mean"))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接