这个问题的灵感来自this other one。
假设我有以下pandas数据帧:
TYPE YEAR DAY VALUE
0 a 2004 10 NaN
1 b 2005 12 NaN
2 c 2006 180 NaN
3 a 2007 127 NaN
4 b 2008 221 NaN
5 c 2008 17 NaN
我必须根据以下dicts字典填写VALUE
列,其格式为{YEAR: {DAY, VALUE}}
:
mydict={2004: {10: 7.1},
2005: {12: 9.19},
2006: {127: 16.04, 180: 12.33},
2007: {55: 21.94, 127: 33.11},
2008: {17: 5.13, 221: 19.17, 300: 10.05}}
上述帖子中给出的答案是使用df.VALUE = df.VALUE.fillna(df.YEAR.map(mydict))
。
如何更改此映射以确保"遵循"我的数据框中的YEAR和DAY列都是什么?
如果我应用上面的代码片段,我当然会:
TYPE YEAR DAY VALUE
0 a 2004 10 {10: 7.1}
1 b 2005 12 {12: 9.19}
2 c 2006 180 {127: 16.04, 180: 12.33}
3 a 2007 127 {55: 21.94, 127: 33.11}
4 b 2008 221 {17: 5.13, 221: 19.17, 300: 10.05}
5 c 2008 17 {17: 5.13, 221: 19.17, 300: 10.05}
相反,我的目标是价值观。
答案 0 :(得分:3)
您可以使用assign
重写该列。
df['VALUE'] = df.apply(lambda x: mydict[x.YEAR][x.DAY], axis=1)
或@MaartenFabré注意到:
df['VALUE'] = df.apply(lambda x: mydict[x.YEAR].get(x.DAY, np.nan), axis=1)
答案 1 :(得分:2)
df1=pd.DataFrame(mydict).stack().to_frame()
df.assign(VALUE=df.set_index(['DAY', 'YEAR']).VALUE.fillna(df1[0]).values)
Out[937]:
TYPE YEAR DAY VALUE
0 a 2004 10 7.10
1 b 2005 12 9.19
2 c 2006 180 12.33
3 a 2007 127 33.11
4 b 2008 221 19.17
5 c 2008 17 5.13
答案 2 :(得分:2)
选项1
使用pd.DataFrame.lookup
df.assign(VALUE=pd.DataFrame(mydict).lookup(df.DAY, df.YEAR))
TYPE YEAR DAY VALUE
0 a 2004 10 7.10
1 b 2005 12 9.19
2 c 2006 180 12.33
3 a 2007 127 33.11
4 b 2008 221 19.17
5 c 2008 17 5.13
选项2
理解+ zip
df.assign(VALUE=[mydict[y][d] for y, d in zip(df.YEAR, df.DAY)])
TYPE YEAR DAY VALUE
0 a 2004 10 7.10
1 b 2005 12 9.19
2 c 2006 180 12.33
3 a 2007 127 33.11
4 b 2008 221 19.17
5 c 2008 17 5.13
答案 3 :(得分:1)
首先从my_dict获取信息,将年份和日期作为索引
df2 = pd.DataFrame.from_dict(mydict).transpose().stack(0)
# df2 = pd.DataFrame(mydict).unstack().dropna() # works too
然后为原始df制作年和日索引,插入sacond索引,并将结果转换回原始形状
df3 = df.set_index(['DAY', 'YEAR'])
df3['VALUE'] = df2
df3.reset_index().reindex(columns=df.columns)