我有一个嵌套字典,其中子字典使用列表:
nested_dict = {'string1': {69: [1231, 232], 67:[682, 12], 65: [1, 1]},
`string2` :{28672: [82, 23], 22736:[82, 93, 1102, 102], 19423: [64, 23]}, ... }
子词典列表中至少有两个元素,但可以有更多。
我想将这本字典“展开”成一个 pandas DataFrame,一列用于第一个字典键(例如'string1','string2',..),一列用于子目录键,一列对于列表中的第一项,一列用于下一项,依此类推。
输出应该是这样的:
col1 col2 col3 col4 col5 col6
string1 69 1231 232
string1 67 682 12
string1 65 1 1
string2 28672 82 23
string2 22736 82 93 1102 102
string2 19423 64 23
当然,我尝试使用 pd.DataFrame.from_dict
:
new_df = pd.DataFrame.from_dict({(i,j): nested_dict[i][j]
for i in nested_dict.keys()
for j in nested_dict[i].keys()
...
现在我卡住了。并且存在很多问题:
如何解析字符串(即
nested_dict[i].values()
)以便每个元素都是一个新的 pandas DataFrame 列?上面实际上不会为每个字段创建一列
以上不会用元素填充列,例如
string1
应该在子目录键值对的每一行中。 (对于col5
和col6
,我可以用零填充NA)我不确定如何正确命名这些列。
最佳答案
这是一个使用递归生成器展开嵌套字典的方法。它不会假定您恰好有两个级别,而是继续展开每个 dict
,直到它到达一个 list
。
nested_dict = {
'string1': {69: [1231, 232], 67:[682, 12], 65: [1, 1]},
'string2' :{28672: [82, 23], 22736:[82, 93, 1102, 102], 19423: [64, 23]},
'string3': [101, 102]}
def unroll(data):
if isinstance(data, dict):
for key, value in data.items():
# Recursively unroll the next level and prepend the key to each row.
for row in unroll(value):
yield [key] + row
if isinstance(data, list):
# This is the bottom of the structure (defines exactly one row).
yield data
df = pd.DataFrame(list(unroll(nested_dict)))
因为 unroll
生成列表的列表而不是字典,所以列将以数字命名(在本例中为 0 到 5)。所以你需要使用 rename
来得到你想要的列标签:
df.rename(columns=lambda i: 'col{}'.format(i+1))
这将返回以下结果(请注意,附加的 string3
条目也已展开)。
col1 col2 col3 col4 col5 col6
0 string1 69 1231 232.0 NaN NaN
1 string1 67 682 12.0 NaN NaN
2 string1 65 1 1.0 NaN NaN
3 string2 28672 82 23.0 NaN NaN
4 string2 22736 82 93.0 1102.0 102.0
5 string2 19423 64 23.0 NaN NaN
6 string3 101 102 NaN NaN NaN
关于python - 将带有列表的嵌套字典展开到 pandas DataFrame 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47840093/