首页 > 解决方案 > 如何从具有部分指定元组键的 dict 在多列索引中设置新列?

问题描述

我有一个按以下方式初始化的熊猫数据框:

import pandas as pd

my_multi_index = pd.MultiIndex.from_tuples([('a', 'a1'), ('a', 'a2'), 
                                            ('b', 'b1'), ('b', 'b2')],
                                           names=['key1', 'key2']) 
df = pd.DataFrame(data=[[1, 2], [3, 4], [5, 6], [7, 8]],
                  columns=['col1', 'col2'],
                  index=my_multi_index)
print(df)

这使:

#            col1  col2
# key1 key2            
# a    a1       1     2
#      a2       3     4
# b    b1       5     6
#      b2       7     8

现在我想desc1使用部分键切片但不在代码中向该数据框添加一个新列,我想从配置中执行此操作,即具有部分元组键的字典:

# i'd like to externalize this and not hardcode it i.e. easier maintenance
df.loc[pd.IndexSlice['a', :], 'desc1'] = 'x'
df.loc[pd.IndexSlice['b', 'b1'], 'desc1'] = 'y1'
df.loc[pd.IndexSlice['b', 'b2'], 'desc1'] = 'y2'
print(df)

这使:

# key1 key2                  
# a    a1       1     2     x
#      a2       3     4     x
# b    b1       5     6    y1
#      b2       7     8    y2

请注意,设置“x”不取决于('a', _)键的第二个组件,而设置“y1”和“y2”确实取决于('b', 'b1')键的第二个组件。(a, _)一个可能的解决方案是完全指定映射,但如果我有一个 100的分配不依赖于第二个组件,这也是不可取的。我希望达到上述结果,但不对切片分配进行硬编码,而是希望从外部化字典中进行:

我的配置字典看起来像这样:

my_dict = {
    ('a', None): 'x',
    ('b', 'b1'): 'y1',
    ('b', 'b2'): 'y2'
}

是否有一种 pythonic 和 pandas-tonic 方法来应用这个字典与部分指定的键来达到之前产生的切片分配?

标签: pythonpandasdataframeslicemulti-index

解决方案


我们可以利用我们可以将元组作为 MultiIndex 切片器传递的事实。此外,我们会稍微调整您的my_dict. 然后我们应用一个简单的 for 循环:

my_dict = {
    ('a',): 'x',
    ('b', 'b1'): 'y1',
    ('b', 'b2'): 'y2'
}

for idx, value in my_dict.items():
    df.loc[idx, 'desc1'] = value
           col1  col2 desc1
key1 key2                  
a    a1       1     2     x
     a2       3     4     x
b    b1       5     6    y1
     b2       7     8    y2

第二种选择是使用Index.map并填写您的字典中的第一个值,因此我们可以使用Series.ffill

my_dict = {
    ('a', 'a1'): 'x',
    ('b', 'b1'): 'y1',
    ('b', 'b2'): 'y2'
}

df['desc1'] = df.index.map(my_dict)
df['desc1'] = df['desc1'].ffill()


           col1  col2 desc1
key1 key2                  
a    a1       1     2     x
     a2       3     4     x
b    b1       5     6    y1
     b2       7     8    y2

推荐阅读