按列名和多索引向多索引数据框添加值

Posted

技术标签:

【中文标题】按列名和多索引向多索引数据框添加值【英文标题】:Adding values to multiindex dataframe by column name as well as multi index 【发布时间】:2018-10-17 10:16:49 【问题描述】:

我仍然对 Pandas 中多索引的工作方式感到很困惑。我创建了一个多索引如下:

import pandas as pd
import numpy as np

arrays = [np.array(['pearson', 'pearson', 'pearson', 'pearson', 'spearman', 'spearman',
                    'spearman', 'spearman', 'kendall', 'kendall', 'kendall', 'kendall']),
          np.array(['PROFESSIONAL', 'PROFESSIONAL', 'STUDENT', 'STUDENT',
                    'PROFESSIONAL', 'PROFESSIONAL', 'STUDENT', 'STUDENT',
                    'PROFESSIONAL', 'PROFESSIONAL', 'STUDENT', 'STUDENT']),
          np.array(['r', 'p', 'r', 'p', 'rho', 'p', 'rho', 'p', 'tau', 'p', 'tau', 'p'])]

tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=['correlator', 'expertise', 'coeff-p'])

然后我用它们制作了一个空的 DataFrame 并添加了一个列名“pair”:

results_df = pd.DataFrame(index=index)
results_df.columns.names = ['pair']

填充了一些玩具数据(results_df['attr1-attr2'] = [1,2,3,4,5,6,7,8,9,10,11,12]),它看起来像这样:

pair                             attr1-attr2
correlator expertise    coeff-p             
pearson    PROFESSIONAL r                  1
                        p                  2
           STUDENT      r                  3
                        p                  4
spearman   PROFESSIONAL rho                5
                        p                  6
           STUDENT      rho                7
                        p                  8
kendall    PROFESSIONAL tau                9
                        p                 10
           STUDENT      tau               11
                        p                 12

但是,我想从字典中添加值而不是假人。对于每个 attr-attr 对,字典中的条目如下所示:

'attr-attr': 
  'pearson': 
    'STUDENT': 
      'r': VALUE,
      'p': VALUE
    ,
    'PROFESSIONAL': 
      'r': VALUE,
      'p': VALUE
    
  ,
  'spearman': 
    'STUDENT': 
      'r': VALUE,
      'p': VALUE
    ,
    'PROFESSIONAL': 
      'r': VALUE,
      'p': VALUE
    
  
  'kendall': 
    'STUDENT': 
      'r': VALUE,
      'p': VALUE
    ,
    'PROFESSIONAL': 
      'r': VALUE,
      'p': VALUE
    
  

以下实际示例数据供您使用:

correlations = 'NormNedit-NormEC_TOT': 'pearson': 'PROFESSIONAL': 'r': 0.13615071018351657, 'p': 0.0002409555504769095, 'spearman': 'STUDENT': 'rho': 0.10867061294616957, 'p': 0.003437711066527592, 'PROFESSIONAL': 'tau': 0.08185775947238913, 'p': 0.003435247172206748, 'kendall': 'STUDENT': 'tau': 0.08185775947238913, 'p': 0.003435247172206748, 'NormLiteral-NormEC_TOT': 'pearson': 'PROFESSIONAL': 'r': 0.13615071018351657, 'p': 0.0002409555504769095, 'STUDENT': 'tau': 0.08185775947238913, 'p': 0.003435247172206748, 'spearman': 'STUDENT': 'rho': 0.10867061294616957, 'p': 0.003437711066527592, 'PROFESSIONAL': 'r': 0.13615071018351657, 'p': 0.0002409555504769095, 'kendall': 'STUDENT': 'tau': 0.08185775947238913, 'p': 0.003435247172206748, 'NormHTra-NormEC_TOT': 'pearson': 'STUDENT': 'r': 0.13615071018351657, 'p': 0.0002409555504769095, 'spearman': 'STUDENT': 'rho': 0.10867061294616957, 'p': 0.003437711066527592, 'PROFESSIONAL': 'r': 0.13615071018351657, 'p': 0.0002409555504769095, 'kendall': 'STUDENT': 'tau': 0.08185775947238913, 'p': 0.003435247172206748, 'NormScatter-NormEC_TOT': 'pearson': 'STUDENT': 'r': 0.13615071018351657, 'p': 0.0002409555504769095, 'spearman': 'STUDENT': 'rho': 0.10867061294616957, 'p': 0.003437711066527592, 'PROFESSIONAL': 'tau': 0.08185775947238913, 'p': 0.003435247172206748, 'kendall': 'PROFESSIONAL': 'tau': 0.08185775947238913, 'p': 0.003435247172206748, 'NormCrossS-NormEC_TOT': 'pearson': 'STUDENT': 'r': 0.13615071018351657, 'p': 0.0002409555504769095, 'PROFESSIONAL': 'rho': 0.10867061294616957, 'p': 0.003437711066527592, 'spearman': 'STUDENT': 'rho': 0.10867061294616957, 'p': 0.003437711066527592, 'PROFESSIONAL': 'rho': 0.10867061294616957, 'p': 0.003437711066527592, 'kendall': 'PROFESSIONAL': 'tau': 0.08185775947238913, 'p': 0.003435247172206748, 'NormPdur-NormEC_TOT': 'pearson': 'STUDENT': 'r': 0.13615071018351657, 'p': 0.0002409555504769095, 'PROFESSIONAL': 'rho': 0.10867061294616957, 'p': 0.003437711066527592, 'spearman': 'STUDENT': 'rho': 0.10867061294616957, 'p': 0.003437711066527592, 'kendall': 'PROFESSIONAL': 'tau': 0.08185775947238913, 'p': 0.003435247172206748

所以对于每个'attr-attr'(最上面的键)作为列名,我想将其值添加到多索引中的相应行。但是,我似乎无法找到一种有效的方法来做到这一点。缺失值应为np.nan。我尝试循环字典并使用query()[],但这没有用。

for attr, attr_d in correlations.items():
    for correl, correl_d in attr_d.items():
        for split, split_d in correl_d.items():
            results_df.query(f"correlator == correl and expertise == split and coeff_p == 'p'")[attr] = split_d['p']
            results_df.query(f"correlator == correl and expertise == split and coeff_p != 'p'")[attr] = split_d['r'] if 'r' in split_d else split_d['rho'] if 'rho' in split_d else split['tau']

> pandas.core.computation.ops.UndefinedVariableError: name 'pearson' is not defined

我知道数据比较复杂,所以如果有不清楚的地方请告诉我。

【问题讨论】:

【参考方案1】:

您可以调整 Wouter Overmeire's answer to this question 以从嵌套字典中创建多索引数据框:

d = correlations
df = pd.DataFrame.from_dict((i,j,k): d[i][j][k]
   for i in d.keys() 
   for j in d[i].keys()
   for k in d[i][j].keys()
   , orient='index').stack()

然后,如果您希望列来自嵌套字典的***别(attr-attr 级别),您可以取消堆叠结果:

df = df.unstack(level=0)

注意:我认为您的示例数据中有错误,其中'PROFESSIONAL': 'STUDENT': ...。如果这不是一个错误,我只是误解了一些东西,请告诉我。

【讨论】:

不幸的是,这并没有给我想要的结构。我希望 attr-attr 作为列,现在它们只是多索引的一部分。 @piRSquared 是在正确的轨道上,但我不确定他们为什么停止工作。 您能发布您希望示例数据输出的样子吗? 就像我提供的玩具数据示例一样,即每个 Norm...-Norm... 对有一列。 您是否检查过您的玩具数据实际上与此相对应?另外,我以我认为可以提供的方式更新了答案。 你是对的,我的错!我编辑了示例代码 - 现在应该是正确的。

以上是关于按列名和多索引向多索引数据框添加值的主要内容,如果未能解决你的问题,请参考以下文章

来自按级别分组的多索引熊猫数据框的子图

转换多索引数据框并按位置更改二级索引

如何更改多索引数据框中的索引

加入数据框 - 一个具有多索引列,另一个没有

按对象将熊猫分组转换为多索引数据框

在多索引数据框中添加新行作为标题