индекс кортежа фрейма данных с многоиндексным и вычитанием 3-го элемента индекса

#python-3.x #pandas #dataframe

#python-3.x #pandas #фрейм данных

Вопрос:

У меня есть такой фрейм данных, как:

     `           a    b    c
    (0,0,a)   1.0  2.0  3.0
    (0,0,b)   4.0  5.0  6.0
    (0,0,c)   7.0  8.0  9.0
    (0,1,a)  10.0 11.0 12.0
    (0,1,b)  13.0 14.0 15.0
    (0,1,c)  16.0 17.0 18.0
    (1,0,a)  19.0 20.0 21.0
    (1,0,b)  22.0 23.0 24.0
    (1,0,c)  26.0 27.0 28.0`
  

If — это многоиндексный df с 3 уровнями, как кортеж.
Теперь я хочу добавить новый столбец с суммой всех строк и вычесть элемент имени столбца = 3-й элемент индексного кортежа, что-то вроде:

     `           a    b    c    new
    (0,0,a)   1.0  2.0  3.0    5.0
    (0,0,b)   4.0  5.0  6.0   10.0
    (0,0,c)   7.0  8.0  9.0   15.0
    (0,1,a)  10.0 11.0 12.0   23.0
    (0,1,b)  13.0 14.0 15.0   28.0
    (0,1,c)  16.0 17.0 18.0   33.0
    (1,0,a)  19.0 20.0 21.0   41.0
    (1,0,b)  22.0 23.0 24.0   46.0
    (1,0,c)  26.0 27.0 28.0   53.0`
  

У меня тот же df с одним индексом, и он работает с:

     ` df['new'] = df.apply(lambda row: sum(row[1:]) - row[row['index'][2]],1)`
  

Но теперь мне нужно изменить некоторые столбцы, и мне нужно перейти к multiindex. Что я могу сделать? перейти на единый индекс? Как? или я могу сохранить мультииндекс в моем df?

Спасибо

Комментарии:

1. Пожалуйста, создайте ответ вместо того, чтобы редактировать его в вопросе.

2. Ответ был отредактирован с df.columns = df.columns.get_level_values(0) помощью, а затем с помощью EDIT .

Ответ №1:

Используйте sum для строк и вычитайте значения, извлеченные DataFrame.lookup с помощью третьих значений кортежей в индексе с помощью str[2] :

 print(df.columns) 
MultiIndex([('a',),
            ('b',),
            ('c',)],
           )

#convert one level DataFrame to simple Index
df.columns = df.columns.get_level_values(0)
print(df.columns) 
Index(['a', 'b', 'c'], dtype='object')

df['new'] = df.sum(axis=1) - df.lookup(df.index, df.index.str[2])
print (df)
              a     b     c   new
(0, 0, a)   1.0   2.0   3.0   5.0
(0, 0, b)   4.0   5.0   6.0  10.0
(0, 0, c)   7.0   8.0   9.0  15.0
(0, 1, a)  10.0  11.0  12.0  23.0
(0, 1, b)  13.0  14.0  15.0  28.0
(0, 1, c)  16.0  17.0  18.0  33.0
(1, 0, a)  19.0  20.0  21.0  41.0
(1, 0, b)  22.0  23.0  24.0  46.0
(1, 0, c)  26.0  27.0  28.0  53.0
  

РЕДАКТИРОВАТЬ: Другая возможная проблема заключается в том, что некоторые значения третьих кортежей не совпадают:

 print(df) 
              a     b     c
(0, 0, d)   1.0   2.0   3.0 <- d not match
(0, 0, e)   4.0   5.0   6.0 <- e not match
(0, 0, c)   7.0   8.0   9.0
(0, 1, a)  10.0  11.0  12.0
(0, 1, b)  13.0  14.0  15.0
(0, 1, c)  16.0  17.0  18.0
(1, 0, a)  19.0  20.0  21.0
(1, 0, b)  22.0  23.0  24.0
(1, 0, c)  26.0  27.0  28.0

#get values of third level
s = df.index.str[2]
#dict of not matched values 
new = dict.fromkeys(np.setdiff1d(s, df.columns), np.nan)
print (new)
{'d': nan, 'e': nan}
  

 #added new columns used for lookup
df1 = df.assign(**new)
print (df1)
              a     b     c   d   e
(0, 0, d)   1.0   2.0   3.0 NaN NaN
(0, 0, e)   4.0   5.0   6.0 NaN NaN
(0, 0, c)   7.0   8.0   9.0 NaN NaN
(0, 1, a)  10.0  11.0  12.0 NaN NaN
(0, 1, b)  13.0  14.0  15.0 NaN NaN
(0, 1, c)  16.0  17.0  18.0 NaN NaN
(1, 0, a)  19.0  20.0  21.0 NaN NaN
(1, 0, b)  22.0  23.0  24.0 NaN NaN
(1, 0, c)  26.0  27.0  28.0 NaN NaN


#used df1 for sum and lookup
df['new'] = df1.sum(axis=1) - df1.lookup(df1.index, s)
print (df)
              a     b     c   new
(0, 0, d)   1.0   2.0   3.0   NaN
(0, 0, e)   4.0   5.0   6.0   NaN
(0, 0, c)   7.0   8.0   9.0  15.0
(0, 1, a)  10.0  11.0  12.0  23.0
(0, 1, b)  13.0  14.0  15.0  28.0
(0, 1, c)  16.0  17.0  18.0  33.0
(1, 0, a)  19.0  20.0  21.0  41.0
(1, 0, b)  22.0  23.0  24.0  46.0
(1, 0, c)  26.0  27.0  28.0  53.0
  

Ответ №2:

После выполнения работы я копирую сообщение об ошибке:

  `    df['new'] = df.sum(axis=1) - df.lookup(df.index, df.index.str[2])
  File ".........", line 3713, in lookup
    raise KeyError('One or more column labels was not found')
  KeyError: 'One or more column labels was not found'
  

`

Я копирую печать индекса:

 `print(df.columns) 
MultiIndex(levels=[['a', 'b', 'c']],
            codes=[[0, 1, 2]])
print(df.index)
Index([(0.0, 0.0, 'a'), (0.0, 0.0, 'b'), (0.0, 0.0, 'c'), (0.0, 1.0, 'a'), (0.0, 1.0, 'b'), (0.0, 1.0, 'c'), (0.0, 2.0, 'a'), (0.0, 2.0, 'b'), (0.0, 2.0, 'c'), (1.0, 0.0, 'a'), (1.0, 0.0, 'b'), (1.0, 0.0, 'c'), (1.0, 1.0, 'a'), (1.0, 1.0, 'b'), (1.0, 1.0, 'c'), (1.0, 2.0, 'a'), (1.0, 2.0, 'b'), (1.0, 2.0, 'c'), (2.0, 0.0, 'a'), (2.0, 0.0, 'b'), (2.0, 0.0, 'c'), (2.0, 1.0, 'a'), (2.0, 1.0, 'b'), (2.0, 1.0, 'c'), (2.0, 2.0, 'a'), (2.0, 2.0, 'b'), (2.0, 2.0, 'c')], dtype='object')
print(df.index.str[2])
Index(['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c'], dtype='object')`
  

Я надеюсь, что это может мне помочь