从字典列表创建 Pandas MultiIndex 的最佳方法是啥?
Posted
技术标签:
【中文标题】从字典列表创建 Pandas MultiIndex 的最佳方法是啥?【英文标题】:What's the best way to create a Pandas MultiIndex from a list of dictionaries?从字典列表创建 Pandas MultiIndex 的最佳方法是什么? 【发布时间】:2019-06-11 03:22:12 【问题描述】:我有一个迭代过程,每次迭代都使用不同的参数值运行,我想收集参数值和结果并将它们放入 Pandas 数据框中,该数据框具有从参数值集(唯一)构建的多索引.
每次迭代,参数值都在字典中,如下所示:
params = 'p': 2, 'q': 7
因此很容易将它们与结果一起收集到一个列表中:
results_index = [
'p': 2, 'q': 7,
'p': 2, 'q': 5,
'p': 1, 'q': 4,
'p': 2, 'q': 4
]
results_data = [
'A': 0.18, 'B': 0.18,
'A': 0.67, 'B': 0.21,
'A': 0.96, 'B': 0.45,
'A': 0.58, 'B': 0.66
]
但我找不到从results_index
生成所需多索引的简单方法。
我试过了:
df = pd.DataFrame(results_data, index=results_index)
但它会产生这个:
A B
'p': 2, 'q': 7 0.18 0.18
'p': 2, 'q': 5 0.67 0.21
'p': 1, 'q': 4 0.96 0.45
'p': 2, 'q': 4 0.58 0.66
(索引没有转换成MultiIndex)
我想要的是这个:
A B
p q
2 7 0.18 0.18
5 0.67 0.21
1 4 0.96 0.45
2 4 0.58 0.66
这可行,但必须有更简单的方法:
df = pd.concat([pd.DataFrame(results_index), pd.DataFrame(results_data)], axis=1).set_index(['p', 'q'])
更新:
此外,这可行,但让我感到紧张,因为我如何确保参数值与级别名称对齐?
index = pd.MultiIndex.from_tuples([tuple(i.values()) for i in results_index],
names=results_index[0].keys())
df = pd.DataFrame(results_data, index=index)
A B
p q
2 7 0.18 0.18
5 0.67 0.21
1 4 0.96 0.45
2 4 0.58 0.66
【问题讨论】:
pd.DataFrame(**x, **y for x,y in zip(results_index, results_data)).set_index(['p', 'q'])
有效,但老实说与您的 concat
解决方案没有太大区别。
【参考方案1】:
我尝试使用 .join()
df1 = pd.DataFrame(results_index)
df2 = pd.DataFrame(results_data)
result = df1.join(df2, how='outer').set_index(['p','q'])
我得到了相同的结果,并且发现这更容易。希望这对您有所帮助。
【讨论】:
【参考方案2】:创建列表字典并传递给MultiIndex.from_arrays
:
#https://***.com/a/33046935
d = k: [dic[k] for dic in results_index] for k in results_index[0]
print(d)
'p': [2, 2, 1, 2], 'q': [7, 5, 4, 4]
mux = pd.MultiIndex.from_arrays(list(d.values()), names=list(d))
df = pd.DataFrame(results_data, index=mux)
print (df)
A B
p q
2 7 0.18 0.18
5 0.67 0.21
1 4 0.96 0.45
2 4 0.58 0.66
【讨论】:
是的,我认为因为似乎没有其他方法,最好的办法是首先收集列表中的所有参数值(检查每次迭代是否参数相同并附加到正确的列表),然后在最后使用pd.MultiIndex.from_arrays
。似乎没有一种简单的方法可以从字典列表中创建多索引。谢谢。
使用pd.MultiIndex.from_frame
查看@santon 的新答案。
@Bill 是的,我明白了。
替代pd.MultiIndex.from_tuples
: tuples = [tuple(d.values()) for d in results_index]; index = pd.MultiIndex.from_tuples(tuples, names=list(result_index.keys())); df = pd.DataFrame(results_data, index=index)
【参考方案3】:
这是@jezrael 答案的变体。稍微简洁一些,并且具有能够处理参数字典中潜在的不一致的好处。但没那么快。
index_df = pd.DataFrame(results_index)
index = pd.MultiIndex.from_arrays(index_df.values.transpose(),
names=index_df.columns)
pd.DataFrame(results_data, index=index)
输出:
A B
p q
2 7 0.18 0.18
5 0.67 0.21
1 4 0.96 0.45
2 4 0.58 0.66
【讨论】:
【参考方案4】:我最近遇到了这个问题,似乎有一种比公认的答案更干净的方法:
results_index = [
'p': 2, 'q': 7,
'p': 2, 'q': 5,
'p': 1, 'q': 4,
'p': 2, 'q': 4
]
results_data = [
'A': 0.18, 'B': 0.18,
'A': 0.67, 'B': 0.21,
'A': 0.96, 'B': 0.45,
'A': 0.58, 'B': 0.66
]
index = pd.MultiIndex.from_frame(pd.DataFrame(results_index))
pd.DataFrame(results_data, index=index)
输出:
A B
p q
2 7 0.18 0.18
5 0.67 0.21
1 4 0.96 0.45
2 4 0.58 0.66
【讨论】:
以上是关于从字典列表创建 Pandas MultiIndex 的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
我需要从包含列表的字典中使用 MultiIndex 在 Pandas 中创建一个 DataFrame
使用元组键从字典创建 MultiIndex pandas DataFrame
构建 MultiIndex pandas DataFrame 嵌套 Python 字典
嵌套字典到 MultiIndex pandas DataFrame(3 级)