将字典值映射到Pandas数据帧列

3

我有一个字典:

 j =  {1: {'help': 2},
 2: {'chocolate': 1, 'help': 1},
 3: {'chocolate': 1, 'help': 1}}

并且这是一个数据帧:
df = pd.DataFrame({'docId': [1, 2, 3, 1, 2, 3, ],
                       'sent': ['help', 'chocolate', 'chocolate', 'help', 'help', 'help']})

我希望根据docId和term匹配值,结果应该如下:

docId  sent        freq
1      help         2
2      chocolate    1
3      chocolate    1
1      help         2
2      help         1
3      help         1

我不确定如何完成这个任务,我尝试使用map和apply但是没有取得任何进展。

3个回答

6

重新定义你的字典

利用元组作为键,您可以使用map函数将get方法映射到压缩的列上。

J = {(x, y): v for x, V in j.items() for y, v in V.items()}

df.assign(freq=[*map(J.get, zip(df.docId, df.sent))])


   docId       sent  freq
0      1       help     2
1      2  chocolate     1
2      3  chocolate     1
3      1       help     2
4      2       help     1
5      3       help     1

或者不用

你可以在map中使用一个带两个参数的lambda函数,并传入提供这些参数的可迭代对象。

df.assign(freq=[*map(lambda x, y: j[x][y], df.docId, df.sent)])

   docId       sent  freq
0      1       help     2
1      2  chocolate     1
2      3  chocolate     1
3      1       help     2
4      2       help     1
5      3       help     1

6
如何使用列表推导式?您可以链接两个 dict.get 调用(一个用于每个嵌套级别)。
df['freq'] = [
    j.get(x, {}).get(y, np.nan) for x, y in df[['docId', 'sent']].values]
df

   docId       sent  freq
0      1       help     2
1      2  chocolate     1
2      3  chocolate     1
3      1       help     2
4      2       help     1
5      3       help     1

如果您能保证j中存在所有条目,您可以将上面的内容简化为:
df['freq'] = [j[x][y] for x, y in df[['docId', 'sent']].values]
df

   docId       sent  freq
0      1       help     2
1      2  chocolate     1
2      3  chocolate     1
3      1       help     2
4      2       help     1
5      3       help     1

当我在嵌套字典中有另一层级时,链式使用dict.get对我很有效。我尝试适应其他答案时遇到了麻烦,如果有人正在尝试更复杂的字典,这可能会有所帮助。 - chasedcribbet

4

如果我理解正确,可以尝试使用reindex来尝试一些不同的东西。

s=pd.DataFrame(j).stack().reindex(pd.MultiIndex.from_arrays([df.sent,df.docId])).reset_index()
s
Out[81]: 
        sent  docId    0
0       help      1  2.0
1  chocolate      2  1.0
2  chocolate      3  1.0
3       help      1  2.0
4       help      2  1.0
5       help      3  1.0

最终使用这种方法 lookup

df['Freq']=pd.DataFrame(j).lookup(df.sent,df.docId)
df
Out[95]: 
   docId       sent  Freq
0      1       help   2.0
1      2  chocolate   1.0
2      3  chocolate   1.0
3      1       help   2.0
4      2       help   1.0
5      3       help   1.0

@ScottBoston 也许你可以尝试使用 merge :-) 我也想看到那个函数的效果 : -) - BENY
我正在尝试合并,但出现了一些dtype问题。 - Scott Boston
1
df.join(pd.DataFrame(j).unstack().rename_axis([*df]).rename('freq'), on=[*df]) - piRSquared
1
@piRSquared 是的,那很好,我最终使用了查找 :-) - BENY
1
哦!lookup我喜欢它! - piRSquared
显示剩余3条评论

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