【发布时间】:2019-12-10 10:49:33
【问题描述】:
原始问题:我使用的是 python 3。我有一些 4 级字典和 5 级字典。我想将这个多级字典转换成带有递归函数的 pandas DataFrame
为了简化我的问题并测试我的函数,我生成了一个如下所示的 3 级字典并尝试我的递归函数。我知道有了这 3 层嵌套字典,还有很多其他方法可以解决这个问题。但是,我觉得只有递归函数才能轻松解决 4 级、5 级或更多级字典的问题
创建一个简化的 3 级字典:
from collections import defaultdict
def ddict():
return defaultdict(ddict)
tree = ddict()
tree['level1_1']['level2_1']['level3_1'] = <pd.Series1>
tree['level1_1']['level2_1']['level3_2'] = <pd.Series2>
tree['level1_1']['level2_2']['level3_1'] = <pd.Series3>
tree['level1_1']['level2_2']['level3_2'] = <pd.Series4>
tree['level1_2']['level2_1']['level3_1'] = <pd.Series5>
tree['level1_2']['level2_1']['level3_2'] = <pd.Series6>
tree['level1_2']['level2_2']['level3_1'] = <pd.Series7>
tree['level1_2']['level2_2']['level3_2'] = <pd.Series8>
受下面Bart Cubrich的启发,我修改了xx的代码并将我的解决方案放在这里
import collections
def tree2df (d, colname):
"""
Inputs:
1. d (a nested dict, or a tree, all values are pd.Series)
2. colname (a list)
Return:
1. a pd.DataFrame
"""
def flatten(d, parent_key='', sep='-'):
items = []
for k, v in d.items():
new_key = str(parent_key) + str(sep) + str(k) if parent_key else k
if isinstance(v, collections.MutableMapping):
items.extend(flatten(v, new_key, sep=sep).items())
else:
items.append((new_key, v))
return dict(items)
flat_dict = flatten (d)
levels, vals = zip(*[(tuple(level.split('-')),val) for level, val in flat_dict.items()])
max_level = np.max(np.array([len(l) for l in levels]))
if len(colname) != max_level:
print ("The numbers of column name is invalid because of moer than maximum level: %s.\nNothing will be returned. Please revise the colname!"%max_level)
else:
colname += ['Old index']
s = pd.concat(list(vals), keys = list(levels), names = colname)
s = pd.DataFrame(s)
s.reset_index(inplace=True)
s.rename(columns={0:'Value'},inplace=True)
return s
#Example
BlockEvent_TS_df = tree2df (BlockEvent_TS_tree, ['ID','Session','Trial type','Block', 'Event name'])
5 级嵌套字典与 3 级嵌套字典的思想相同:
tree['level1_1']['level2_1']['level3_1']['level4_1']['level5_1'] = <pd.Series1>
...
tree['level1_2']['level2_2']['level3_2']['level4_2']['level5_2'] = <pd.Series32>
因为我有一个很大的数据集,所以在这里显示整个嵌套字典非常复杂。但是,想法是这样的。稍后,我希望有 6 列,5 列来存储每个级别,并且一列用于值。
我已经尝试了上面的代码,它对我来说效果很好。速度也很不错。
感谢您的帮助!
【问题讨论】:
-
你能提供一个实际的 5 级字典的例子,让它更清楚吗?
-
数据集太大,无法在此处实际输入。但是,它应该与创建 3 级字典的方式相同。只需添加更多级别,对于每个级别,我都想转换为数据框中的一列。我可以编辑我的帖子以说明更多内容。
-
您使用
defaultdict是否有特定原因? -
另外,您的问题是什么?你的代码有什么问题?
标签: python python-3.x pandas dictionary recursion