Как лучше всего создать Pandas MultiIndex из списка словарей? - PullRequest
0 голосов
/ 17 января 2019

У меня есть итеративный процесс, который выполняется с разными значениями параметров на каждой итерации, и я хочу собрать значения параметров и результаты и поместить их в фрейм данных 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

(индекс не преобразован в мультииндекс)

Я хочу вот что:

        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'])

UPDATE:

Кроме того, это работает, но заставляет меня нервничать, потому что как я могу быть уверен, что значения параметров выровнены с именами уровней?

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

Ответы [ 3 ]

0 голосов
/ 17 января 2019

Создать словарь списков и перейти к 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
0 голосов
/ 17 января 2019

Это вариант ответа @ 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
0 голосов
/ 17 января 2019

Я пытался с .join ()

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

Я получил те же результаты и нашел это проще. Надеюсь, это поможет вам.

...