Pandas MultiIndex нарезка без сортировки - PullRequest
1 голос
/ 18 марта 2020

Учитывая 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 Ответ

1 голос
/ 18 марта 2020

Это хорошо работает в последней версии pandas.

Если невозможно обновление pandas, возможно выбрать уровни по маскам, созданным Index.get_level_values и Index.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
...