我有两个数据帧df_country_cluster
和df_countries
,具有以下结构(按顺序):
cluster_id
country_id
1 4
2 4
... ...
col1 col2 col3 col4
country_id year_id
1 2015 0.1 0.2 0.3 0.1
1 2016 0.4 NaN 0.1 0.8
1 2017 0.7 0.2 0.6 NaN
1 2018 0.9 0.4 0.7 0.2
2 2015 0.5 0.6 NaN 0.3
2 2016 0.3 0.7 0.2 0.5
2 2017 0.2 0.9 0.3 0.5
2 2018 0.1 0.2 0.1 0.9
... ... ... ... ... ...
我的目标是用每个群集和年份的平均非NaN值填充NaN值。这意味着,例如,country_id
1,year_id
2016,col2
中的NaN应该用col2
在2016年的有效值的平均值和所有cluster_id
为4(在这种情况下)的国家/地区。
在上面的示例中,我们将以这种方式获得cluster_id
4的平均值:
col1 col2 col3 col4
cluster_id year_id
4 2015 0.3 0.4 *0.3 0.2
4 2016 0.4 *0.7 0.2 0.6
4 2017 0.4 0.6 0.4 *0.5
4 2018 0.5 0.3 0.4 0.6
因此,NaN每列将用*填充值。
我尝试用DataFrame
创建一个新的groupby().mean()
,然后使用.fillna
,但没有成功。其他SO问题like this仅讨论单索引问题。
这是我的方法:
cols = ['col1','col2','col3','col4']
original_index = df_countries.index
df_countries = df_countries.join(df_country_cluster,on='country_id')
df_countries = df_countries.reset_index().set_index(['cluster_id','year_id'])
avg_cluster = df_countries.groupby(['cluster_id','year_id']).mean()
avg_cluster = avg_cluster[cols]
for col in cols:
df_countries[col].fillna(avg_cluster[col],inplace=True)
df_countries.reset_index().set_index(original_index)
答案 0 :(得分:0)
我不确定我是否理解正确。但是您的方法看起来不错。所以我们从
开始df = df_countries.join(df_country_cluster, on='country_id')
df = df.reset_index().set_index(['cluster_id','year_id'])
您说填充值是每组的平均值:
s = df[['col1', 'col2', 'col3', 'col4']].mean(axis=1)
如果我们转置DataFrame,我们可以放在一起
df = df.T.fillna(value=s).T
最后,我们放弃了不需要的东西
df = df.reset_index().drop(columns='cluster_id').set_index('country_id', 'year_id')
答案 1 :(得分:0)
知道了。
df_countries = df_countries.reset_index().set_index(original_index)
忘记用正确的索引来保留答案...通过此更改,它可以工作。 但是,如果有人有更Python化的方法,请添加答案!