Добавить промежуточные столбцы в пандах с мультииндекс

У меня есть фреймворк с 3-уровневым глубоким мультииндексиром на столбцах. Я хотел бы вычислить промежуточные sum(axis=1) по строкам ( sum(axis=1) ), где я суммируюсь на одном из уровней, сохраняя остальные. Я думаю, что знаю, как это сделать, используя аргумент ключевого слова level pd.DataFrame.sum . Однако у меня возникают проблемы с тем, как включить результат этой суммы обратно в исходную таблицу.

Настроить:

 import numpy as np import pandas as pd from itertools import product np.random.seed(0) colors = ['red', 'green'] shapes = ['square', 'circle'] obsnum = range(5) rows = list(product(colors, shapes, obsnum)) idx = pd.MultiIndex.from_tuples(rows) idx.names = ['color', 'shape', 'obsnum'] df = pd.DataFrame({'attr1': np.random.randn(len(rows)), 'attr2': 100 * np.random.randn(len(rows))}, index=idx) df.columns.names = ['attribute'] df = df.unstack(['color', 'shape']) 

Придает красивый кадр:

Оригинальная рамка

Скажем, я хотел уменьшить уровень shape . Я мог бы запустить:

 tots = df.sum(axis=1, level=['attribute', 'color']) 

чтобы получить мои итоги так:

общие данные

Как только у меня есть это, я хотел бы применить его к исходному фрейму. Я думаю, что могу сделать это несколько громоздким способом:

 tots = df.sum(axis=1, level=['attribute', 'color']) newcols = pd.MultiIndex.from_tuples(list((i[0], i[1], 'sum(shape)') for i in tots.columns)) tots.columns = newcols bigframe = pd.concat([df, tots], axis=1).sort_index(axis=1) 

совокупный

Есть ли более естественный способ сделать это?

2 Solutions collect form web for “Добавить промежуточные столбцы в пандах с мультииндекс”

Вот путь без петель:

 s = df.sum(axis=1, level=[0,1]).T s["shape"] = "sum(shape)" s.set_index("shape", append=True, inplace=True) df.combine_first(sT) 

Хитрость заключается в использовании транспонированной суммы. Таким образом, мы можем вставить другой столбец (т.е. строку) с именем дополнительного уровня, который мы называем точно так же, как тот, который мы суммировали. Этот столбец можно преобразовать в уровень в индексе с помощью set_index . Затем мы объединяем df с транспонированной суммой. Если суммарный уровень не является последним, вам может потребоваться некоторое переупорядочение уровня.

Вот мой грубой способ сделать это.

После выполнения вашего хорошо написанного (спасибо) образца кода я сделал следующее:

 attributes = pd.unique(df.columns.get_level_values('attribute')) colors = pd.unique(df.columns.get_level_values('color')) for attr in attributes: for clr in colors: df[(attr, clr, 'sum')] = df.xs([attr, clr], level=['attribute', 'color'], axis=1).sum(axis=1) df 

Что дает мне:

большой стол

  • Панды: как избавиться от колонки «Без имени:» в фрейме данных
  • Преобразование данных в словарь списка кортежей
  • Добавьте знак процента в столбец dataframe в Python
  • rpy2 импорт не работает
  • Pandon Pandas - переупорядочивание столбцов в фрейме данных на основе имени столбца
  • Групповой фрейм и получить сумму И счет?
  • Ошибка pyspark: AttributeError: объект 'SparkSession' не имеет атрибута 'parallelize'
  • pandas падает при повторном DataFrame.reset_index ()
  • Объединяйте данные о кадрах панд, где одно значение находится между двумя другими
  • Понимание этого сценария Pandas
  • Получить метки строк и столбцов для выбранных значений в кадре данных Pandas
  • Python - лучший язык программирования в мире.