从词典列表创建Pandas MultiIndex的最佳方法是什么?

时间:2019-01-17 00:07:15

标签: python pandas dictionary dataframe multi-index

我有一个迭代过程,每次迭代都使用不同的参数值运行,我想收集参数值和结果并将其放入具有从参数值集(唯一)建立的多索引的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

4 个答案:

答案 0 :(得分:2)

创建列表字典并传递到MultiIndex.from_arrays

#https://stackoverflow.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

答案 1 :(得分:1)

我尝试使用.join()

df1 = pd.DataFrame(results_index)
df2 = pd.DataFrame(results_data)
result = df1.join(df2, how='outer').set_index(['p','q'])

我得到了相同的结果,发现这更容易。希望这对您有所帮助。

答案 2 :(得分:1)

我最近遇到了这个问题,似乎有比接受的答案更简洁的方法:

        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

输出:

timezone

答案 3 :(得分:0)

这是@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
相关问题