Сумма столбцов на основе группировки

#python #pandas

Вопрос:

 d = {'a': [0,1,0,1,1,1], 'b': [1,1,1,1,1,1], 'c': [0,0,0,0,0,1], 'd': [1,0,1,1,1,0]} dct = {'a':'top','b':'bot','c':'top','d':'bot'} df = pd.DataFrame(d)  

Итак, у меня есть df и словарь, который присваивает каждый столбец группе. Возникли проблемы с созданием функции, которая создает столбец total(сумма) для группы. Это будет вывод первых 2 строк:

a b c d итого топ итого_бот
0 1 0 1 0 2
1 1 0 0 1 1

и так далее…. В идеале использовать фрейм данных и имя группы в качестве входных данных

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

1. Я этого не понимаю. Как вы подсчитываете суммы?

2. В словаре a amp; c имеют значение «сверху». Во фрейме данных я хочу суммировать столбец a и c

Ответ №1:

Попробуйте выполнить следующие действия —

 sums = df.rename(columns=dct).stack().groupby(level=(0,1)).sum().unstack() df_new = df.join(sums) df_new  
 a b c d bot top 0 0 1 0 1 2 0 1 1 1 0 0 1 1 2 0 1 0 1 2 0 3 1 1 0 1 2 1 4 1 1 0 1 2 1 5 1 1 1 0 1 2  

Объяснение —

  1. df.rename(columns=dct) переименовывает имена столбцов top в словарь и на bot его основе dct
 df.rename(columns=dct)   top bot top bot 0 0 1 0 1 1 1 1 0 0 2 0 1 0 1 3 1 1 0 1 4 1 1 0 1 5 1 1 1 0  
  1. Затем stack() сложите строки так, чтобы у вас был один столбец с 1 и 0 и несколькими индексами.
 df.rename(columns=dct).stack()  0 top 0  bot 1  top 0  bot 1 1 top 1  bot 1  top 0  bot 0 2 top 0  bot 1  top 0  bot 1 3 top 1  bot 1  top 0  bot 1 4 top 1  bot 1  top 0  bot 1 5 top 1  bot 1  top 1  bot 0 dtype: int64  
  1. Groupby с sum() группами на уровне 0 (индексы строк) и уровне 1 (столбец с верхними и ботовыми значениями) и суммирует 1
 df.rename(columns=dct).stack().groupby(level=(0,1)).sum()  0 bot 2  top 0 1 bot 1  top 1 2 bot 2  top 0 3 bot 2  top 1 4 bot 2  top 1 5 bot 1  top 2 dtype: int64  
  1. Unstack чтобы вернуть 2 колонки top и bot
 df.rename(columns=dct).stack().groupby(level=(0,1)).sum().unstack()   bot top 0 2 0 1 1 1 2 2 0 3 2 1 4 2 1 5 1 2  
  1. Наконец, просто присоедините оригинал df к этому новому sums фрейму данных поверх индексов.
 df.join(sums)   a b c d bot top 0 0 1 0 1 2 0 1 1 1 0 0 1 1 2 0 1 0 1 2 0 3 1 1 0 1 2 1 4 1 1 0 1 2 1 5 1 1 1 0 1 2  

Ответ №2:

  1. map имена столбцов для групп
  2. groupby результирующие значения вдоль оси=1 и sum
  3. add_prefix столбцам для присвоения имен
  4. join Для df
 gt;gt;gt; df.join(df.groupby(df.columns.map(dct), axis=1).sum().add_prefix("total_"))   a b c d total_bot total_top 0 0 1 0 1 2 0 1 1 1 0 0 1 1 2 0 1 0 1 2 0 3 1 1 0 1 2 1 4 1 1 0 1 2 1 5 1 1 1 0 1 2  

Ответ №3:

Группируйтесь dct и присоединяйтесь обратно:

 grouped = df.groupby(dct, axis = 1).sum().add_prefix('total_')  pd.concat([df, grouped], axis = 1)    a b c d total_bot total_top 0 0 1 0 1 2 0 1 1 1 0 0 1 1 2 0 1 0 1 2 0 3 1 1 0 1 2 1 4 1 1 0 1 2 1 5 1 1 1 0 1 2