更新:使用列表推导和 itertuples 和嵌套字典推导。这是最快的
l = [{k: v for k, v in tup._asdict().items() if v is not None}
for tup in d.itertuples(index=False)]
Out[74]: [{'a': 1, 'b': 'a'}, {'a': 2, 'b': 'b'}, {'a': 3}]
时间:
d1 = pd.concat([d]*5000, ignore_index=True)
In [76]: %timeit [{k: v for k, v in tup._asdict().items() if v is not None} for
...: tup in d1.itertuples(index=False)]
442 ms ± 28 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
另一种方法是使用列表理解和iterrows
l = [row.dropna().to_dict() for k, row in d.iterrows()]
Out[33]: [{'a': 1, 'b': 'a'}, {'a': 2, 'b': 'b'}, {'a': 3}]
iterrows 以性能缓慢着称。我对 15000 行样本进行了测试,以与 stack 进行比较
In [49]: d1 = pd.concat([d]*5000, ignore_index=True)
In [50]: %timeit d1.stack().groupby(level=0).agg(lambda x : x.reset_index(level
...: =0,drop=True).to_dict()).tolist()
7.52 s ± 370 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [51]: %timeit [row.dropna().to_dict() for k, row in d1.iterrows()]
6.45 s ± 60.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
有趣的结果。但是,我认为如果数据更大,它会比stack慢