You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将Pandas DataFrame中两列列表转换为包含重复键的字典列

解决Pandas中列表转字典时重复键的值收集问题

嘿,我太懂你的困扰了!你现在用dict(zip(*x))的核心问题在于——字典的键是唯一的,当同一个键多次出现时,后面的值会直接覆盖前面的,根本留不住所有对应的值。要实现把重复键的对应值收集成列表的需求,咱们换个思路构建字典就行。

方法一:使用collections.defaultdict(推荐,高效又好读)

咱们可以自定义一个处理函数,遍历每行的namevalue配对,把每个值追加到对应键的列表里:

from collections import defaultdict

def build_key_value_dict(row):
    # 初始化一个默认值为列表的字典,不用手动判断键是否存在
    result_dict = defaultdict(list)
    # 遍历每一组name和value的配对
    for name, val in zip(row['name'], row['value']):
        result_dict[name].append(val)
    # 转成普通字典(如果不需要defaultdict的特性的话)
    return dict(result_dict)

# 把函数应用到DataFrame的每一行
self.data['dict'] = self.data.apply(build_key_value_dict, axis=1)

这个方法只需要遍历一次配对列表,效率很高,逻辑也直白,后续维护起来也省心。用你的示例测试的话,第一行的结果就是{'a': [1,4], 'b': [2], 'c': [3]},完全符合你的预期。

方法二:用字典推导式(简洁但效率稍低)

如果想写得更紧凑,也可以用字典推导式,不过这种方式对每个键都要重新遍历一遍配对列表,当列表很长时,效率会不如第一种方法:

self.data['dict'] = self.data.apply(
    lambda row: {
        key: [val for name, val in zip(row['name'], row['value']) if name == key]
        for key in set(row['name'])
    },
    axis=1
)

为啥原来的代码不行?

你之前的dict(zip(*x))本质是把namevalue按顺序配对后生成字典,但字典的键唯一性规则会导致:重复键的最后一次出现会覆盖之前所有对应的值。比如第一个示例里的a,最后一次对应的4会替换掉之前的1,所以最终字典里a的值只剩4

内容的提问来源于stack exchange,提问作者Pedro Azevedo

火山引擎 最新活动