Pandas具有很好的功能,可通过pd.to_dict('records')
将数据框导出到字典列表中。
例如:
d = pd.DataFrame({'a':[1,2,3], 'b':['a', 'b', None]})
d.to_dict('records')
返回
[{'a': 1, 'b': 'a'}, {'a': 2, 'b': 'b'}, {'a': 3, 'b': None}]
对于我的用例,我希望输入以下内容:
[{'a': 1, 'b': 'a'}, {'a': 2, 'b': 'b'}, {'a': 3}]
您可以看到b
的键已从第三项中删除。这是使用jsonlite
时R中的默认行为,我想知道如何从每个条目中删除缺少值的键。
答案 0 :(得分:3)
我们可以做stack
l=d.stack().groupby(level=0).agg(lambda x : x.reset_index(level=0,drop=True).to_dict()).tolist()
Out[142]: [{'a': 1, 'b': 'a'}, {'a': 2, 'b': 'b'}, {'a': 3}]
答案 1 :(得分:2)
更新:使用列表推导和itertuples
嵌套dict推导。这是最快的
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
答案 2 :(得分:2)
将所有内容都转储到字典中,列表理解应该更快,更容易:
[{key:value
for key,value in entry.items()
if value is not None}
for entry in d.to_dict('records')]
[{'a': 1, 'b': 'a'}, {'a': 2, 'b': 'b'}, {'a': 3}]
答案 3 :(得分:1)
这里是apply
和series.dropna()
的另一种方法(如果性能不是问题)
d.apply(lambda x: x.dropna().to_dict(),axis=1).tolist()
[{'a': 1, 'b': 'a'}, {'a': 2, 'b': 'b'}, {'a': 3}]