Pandas 用给定分组的平均值替换 nan
Pandas replace nan with mean value for a given grouping
我有一个大型数据集,其形式为:
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 median/mean 值替换 NaN 值。
我尝试了一些类似
的方法
df.fillna(df.groupby('period_id', 'gic_subindustry_id').transform('mean')),
但这似乎慢得令人痛苦(我在几分钟后停止了它)。
我想到它可能变慢的原因是重新计算遇到的每个 NaN 的平均值。为了解决这个问题,我认为计算每个 period_id 的平均值,然后 replacing/mapping 每个 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 映射到这些方法。而且,确实,这是执行此映射的 'correct' 方式吗?速度实际上并不是最重要的,但是 < 60 秒就不错了。
您可以使用 fillna
使用 group-by 的结果,前提是数据帧具有相同的结构(由 as_index=False
给出):
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
我认为下面的代码是正确的。
b = a.fillna(a.groupby(['period_id', 'gic_subindustry_id']).transform("mean"))
我有一个大型数据集,其形式为:
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 median/mean 值替换 NaN 值。
我尝试了一些类似
的方法df.fillna(df.groupby('period_id', 'gic_subindustry_id').transform('mean')), 但这似乎慢得令人痛苦(我在几分钟后停止了它)。
我想到它可能变慢的原因是重新计算遇到的每个 NaN 的平均值。为了解决这个问题,我认为计算每个 period_id 的平均值,然后 replacing/mapping 每个 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 映射到这些方法。而且,确实,这是执行此映射的 'correct' 方式吗?速度实际上并不是最重要的,但是 < 60 秒就不错了。
您可以使用 fillna
使用 group-by 的结果,前提是数据帧具有相同的结构(由 as_index=False
给出):
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
我认为下面的代码是正确的。
b = a.fillna(a.groupby(['period_id', 'gic_subindustry_id']).transform("mean"))