代码之家  ›  专栏  ›  技术社区  ›  Bill

从字典列表中创建熊猫多索引的最佳方法是什么?

  •  1
  • Bill  · 技术社区  · 6 年前

    我有一个迭代过程,每次迭代都使用不同的参数值运行,我想收集参数值和结果,并将它们放在一个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'])
    

    更新:

    同样,这也有效,但会让我紧张,因为我如何才能确保参数值与级别名称对齐?

    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 回复  |  直到 6 年前
        1
  •  2
  •   jezrael    6 年前

    创建列表字典并传递给 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
    
        2
  •  1
  •   CAppajigowda    6 年前

    我尝试了.join()。

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

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

        3
  •  0
  •   Bill    6 年前

    这是@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