熊猫多索引切片无需排序

时间:2020-03-18 10:06:08

标签: python pandas dataframe sorting multi-index

给出具有多索引列的DataFrame

import pandas as pd
fish = [("Fish", lli) for lli in ["One", "Two"]]
dogs = [("Dog", lli) for lli in ["Three", "Four", "Five"]]
cats = [("Cat", lli) for lli in ["Three", "Four", "Five"]]
df = pd.DataFrame(index=["Blue", "Green", "Red"], columns=pd.MultiIndex.from_tuples(fish+dogs+cats))

-

df =

          Fish       Dog              Cat          
          One  Two   Three Four Five  Three Four Five
   Blue   NaN  NaN   NaN   NaN  NaN   NaN   NaN  NaN
   Green  NaN  NaN   NaN   NaN  NaN   NaN   NaN  NaN
   Red    NaN  NaN   NaN   NaN  NaN   NaN   NaN  NaN

现在我想同时设置两列的值,例如

df.loc[:, ('Dog', ['Four', 'Five'])] = 3.1

这导致出现KeyError提示

KeyError: 'MultiIndex Slicing requires the index to be fully lexsorted tuple len (2), lexsort depth (0)'

可以通过在使用设置值之前对列进行排序来“解决”问题

df = df.sort_index(axis=1)

现在的问题是,我不想对列进行排序,因为它们已经以反映所需输出的方式进行了排序。 有什么方法可以设置多个列的值而不先排序吗?

1 个答案:

答案 0 :(得分:1)

在最新版本的熊猫中效果很好。

如果不可能的话,可以通过Index.get_level_valuesIndex.isin创建的遮罩选择级别,并设置以下值:

m1 = df.columns.get_level_values(0) == 'Dog'
m2 = df.columns.get_level_values(1).isin(['Four','Five'])

df.loc[:, m1 & m2] = 3.1
print (df)
      Fish        Dog             Cat          
       One  Two Three Four Five Three Four Five
Blue   NaN  NaN   NaN  3.1  3.1   NaN  NaN  NaN
Green  NaN  NaN   NaN  3.1  3.1   NaN  NaN  NaN
Red    NaN  NaN   NaN  3.1  3.1   NaN  NaN  NaN