将带有元组作为键的嵌套字典转换为数据框

Posted

技术标签:

【中文标题】将带有元组作为键的嵌套字典转换为数据框【英文标题】:Convert a nested dictionary with tuples as keys to a dataframe 【发布时间】:2021-12-29 12:56:15 【问题描述】:

所以我有以下字典:

user_dict = 'user1': 'id1': ('word1', 'word2'): 0.99, ('word3', 'word4'): 0.16,
                       'id2': ('word5', 'word6'): 0.73, ('word7', 'word8'): 0.69,
             'user2': 'id3': ('word9', 'word10'): 0.59, ('word11', 'word12'): 0.13,
                       'id4': ('word13', 'word14'): 0.41, ('word14', 'word15'): 0.74

出于我的目的,我想将嵌套字典转换为以下形式的 pandas 数据框:

  user  |  id  |  w1   |  w2   | score
---------------------------------------
  user1 |  id1 | word1 | word2 | 0.99
        |      | word3 | word4 | 0.16
        |  id2 | word5 | word6 | 0.73   and so on.

我之前尝试过几种方法,这是我目前的解决方案:

df = pd.Series((i,j): user_dict[i][j]
                      for i in user_dict.keys()
                      for j in user_dict[i].keys()).rename_axis(['user', 'id']).reset_index(name='Col3')

所以输出是:

 user  |  id  |                        Col3
 -------------------------------------------------------------------
 user1 |  id1 | ('word1', 'word2'): 0.99, ('word3', 'word4'): 0.16)
 user1 |  id2 | ('word5', 'word6'): 0.73, ('word7', 'word8'): 0.69)    and so on.

谁能告诉我最后几列我做错了什么?

【问题讨论】:

【参考方案1】:

您可以使用嵌套列表理解/生成器:

df = pd.DataFrame(([k0, k1, *k2, d2]
                   for k0, d0  in user_dict.items()
                   for k1, d1 in d0.items()
                   for k2, d2 in d1.items()
                   ), columns=['user', 'id', 'w1', 'w2', 'score'])

输出:

    user   id      w1      w2  score
0  user1  id1   word1   word2   0.99
1  user1  id1   word3   word4   0.16
2  user1  id2   word5   word6   0.73
3  user1  id2   word7   word8   0.69
4  user2  id3   word9  word10   0.59
5  user2  id3  word11  word12   0.13
6  user2  id4  word13  word14   0.41
7  user2  id4  word14  word15   0.74

【讨论】:

没问题!伟大的思想都一样:) 我明白了? 你能解释一下 k2 的 * 是什么意思吗? 这是将元组扩展为单个元素。尝试删除它,看看会发生什么;) 哦,我明白了!感谢您的回答和解释!我会尝试删除它,看看会发生什么!【参考方案2】:

或者,使用更少的循环:

>>> pd.concat(k: pd.DataFrame(v) for k, v in user_dict.items()).melt(ignore_index=False).dropna()

                    variable  value
user1 word1  word2       id1   0.99
      word3  word4       id1   0.16
      word5  word6       id2   0.73
      word7  word8       id2   0.69
user2 word9  word10      id3   0.59
      word11 word12      id3   0.13
      word13 word14      id4   0.41
      word14 word15      id4   0.74

【讨论】:

哦,我以前不知道melt功能。谢谢你的回答! @Steele,以前有一个类似的答案(现在已删除)。这种方法的问题在于它的扩展性非常差。生成许多​​数据帧只是为了连接它们是非常昂贵的。我没有测试你的版本,之前的答案慢了 500 倍(嵌套循环和单个 DataFrame 构造函数为 10 秒 vs 20 毫秒)

以上是关于将带有元组作为键的嵌套字典转换为数据框的主要内容,如果未能解决你的问题,请参考以下文章

将字典转换为数据框,键作为列名,键值作为数据框的列值

将带有嵌套字典的json响应转换为pandas数据框[重复]

将带有元组键(key1,key2)的字典转换为数据框,当key1是索引并且key2时,值是列

使用元组键将 Pandas 数据框转换为字典以进行三元图

将熊猫数据框转换为具有多个键的字典

将数据框转换为字典 [重复]