字典列表转Pandas DataFrame:寻求更优时间复杂度的实现方案
将含缺失键的字典列表转换为Pandas DataFrame的优化方案
问题背景
我有一个字典列表:
[{'a':'jeffrey','b':'pineapple','c':'apple'},{'a':'epstein','c':'banana'},{'a':'didnt kill'},{'a':'himself','b':'jebus'}]
希望将其转换为Pandas DataFrame,缺失键对应的值填充为0。我用defaultdict实现了转换,代码如下:
from collections import defaultdict dd = defaultdict(list) for d in l: for k in d.keys(): dd[k] for d in l: for k in dd.keys(): try: dd[k].append(d[k]) except KeyError: dd[k].append(0)
这段代码能生成预期结果:
defaultdict(<class 'list'>, {'a': ['jeffrey', 'epstein', 'didnt kill', 'himself'], 'b': ['pineapple', 0, 0, 'jebus'], 'c': ['apple', 'banana', 0, 0]})
但想知道有没有更优的替代方案,或者时间复杂度更低的实现方式。
优化方案
方法1:直接使用Pandas原生构造函数(最简最优选)
Pandas的DataFrame构造函数本身就支持处理含缺失键的字典列表,缺失值会自动填充为NaN,之后只需用fillna把NaN替换成0即可,一行代码搞定:
import pandas as pd l = [{'a':'jeffrey','b':'pineapple','c':'apple'},{'a':'epstein','c':'banana'},{'a':'didnt kill'},{'a':'himself','b':'jebus'}] df = pd.DataFrame(l).fillna(0)
生成的DataFrame完全符合需求:
a b c 0 jeffrey pineapple apple 1 epstein 0 banana 2 didnt kill 0 0 3 himself jebus 0
时间复杂度:O(n*m)(n是字典数量,m是总键数),和原代码复杂度相当,但Pandas底层是C实现,实际运行效率远高于纯Python循环。
方法2:预提取所有键,一次循环补全字典
先收集所有唯一键,然后遍历每个字典,用dict.get()补全缺失的键为0,再转成DataFrame:
import pandas as pd l = [{'a':'jeffrey','b':'pineapple','c':'apple'},{'a':'epstein','c':'banana'},{'a':'didnt kill'},{'a':'himself','b':'jebus'}] all_keys = {k for d in l for k in d} filled_dicts = [{k: d.get(k, 0) for k in all_keys} for d in l] df = pd.DataFrame(filled_dicts)
时间复杂度:O(n*m),但只需要一轮完整循环(原代码是两轮循环),纯Python层面效率比原代码高,逻辑也更清晰。
方法3:用collections.ChainMap简化键收集
可以用ChainMap快速合并所有字典的键集合,再补全每个字典,代码更简洁:
from collections import ChainMap import pandas as pd l = [{'a':'jeffrey','b':'pineapple','c':'apple'},{'a':'epstein','c':'banana'},{'a':'didnt kill'},{'a':'himself','b':'jebus'}] all_keys = ChainMap(*l).keys() filled_dicts = [{k: d.get(k, 0) for k in all_keys} for d in l] df = pd.DataFrame(filled_dicts)
这个方法和方法2逻辑一致,只是键收集步骤更高效,适合字典数量较多的场景。
方案对比
- 原代码:纯Python两轮循环,逻辑繁琐,运行效率最低。
- 方法1:Pandas原生实现,代码极简,效率最高(底层C优化),推荐优先使用。
- 方法2/3:纯Python层面优化,逻辑清晰,效率优于原代码,适合不想依赖Pandas自动处理缺失值的场景。
内容的提问来源于stack exchange,提问作者INGl0R1AM0R1
相关产品推荐
相关产品推荐

