Как добавить grandtotal столбца в фрейме данных сводной таблицы pandas - PullRequest
0 голосов
/ 26 сентября 2019

Требуется добавить общее количество столбцов в фрейме данных сводной таблицы

У меня есть информационный фрейм сводной таблицы, и мне нужно добавить подколонку, которая в сумме составляет Bill2

data_frame1 = pd.pivot_table(data_frame, index=['PC', 'Geo', 'Comp'], values=['Bill1', 'Bill2'], columns=['Month'], fill_value=0)
data_frame1 = data_frame1.swaplevel(0,1, axis=1).sort_index(axis=1)
tuples = [(a.strftime('%b-%y'), b) if a!= 'All' else (a,b) for a,b in data_frame1.columns]
data_frame1.columns = pd.MultiIndex.from_tuples(tuples)

выход:

              OCT-19             Nov-19        Dec-19
             Bill1 Bill2      Bill1 Bill2     Bill1 Bill2      
PC Geo Comp
A  Ind   OS   1     1         1         1       1        1   

желаемый вывод:

               OCT-19             Nov-19            Dec-19
              Bill1  Bill2     Bill1 Bill2    Bill1 Bill2  FY19-Total   
PC Geo Comp
A  Ind   OS    1      1          1     1        1    1       3

1 Ответ

1 голос
/ 26 сентября 2019

Выберите MultiIndex с помощью xs и sum, выход присваивается кортежу для MultiIndex:

df[('','total')] = df.xs('Bill2', axis=1, level=1).sum(axis=1)
print (df)
         Sep-19       Oct-19       Nov-19            
          Bill1 Bill2  Bill1 Bill2  Bill1 Bill2 total
A Ind OS      1     1      1     1      1     4     6

Для фильтрации по нескольким годам, например, только 2019 необходим фильтр по маске перед:

print (df)
         Sep-20       Oct-19       Nov-19      
          Bill1 Bill2  Bill1 Bill2  Bill1 Bill2
A Ind OS      1     1      1     7      1     4

#convert first level for datetimes and then to years
level0 = pd.to_datetime(df.columns.get_level_values(0), format='%b-%y').year
print (level0)
Int64Index([2020, 2020, 2019, 2019, 2019, 2019], dtype='int64')

mask = level0 == 2019
df[('','total2019')] = df.loc[:, mask].xs('Bill2', axis=1, level=1).sum(axis=1)
print (df)
         Sep-20       Oct-19       Nov-19                
          Bill1 Bill2  Bill1 Bill2  Bill1 Bill2 total2019
A Ind OS      1     1      1     7      1     4        11

РЕДАКТИРОВАТЬ:

Для правильной сортировки после добавления необходима новая строка суммы при работе с датами (или периодами), решение:

print (df)
         Nov-19       Dec-19       Jan-20      
          Bill1 Bill2  Bill1 Bill2  Bill1 Bill2
A Ind OS      1  1.28      1  1.28      1  1.28

level0 = pd.to_datetime(df.columns.get_level_values(0), format='%b-%y')
level1 = df.columns.get_level_values(1)
print (level0)
DatetimeIndex(['2019-11-01', '2019-11-01', '2019-12-01', '2019-12-01',
               '2020-01-01', '2020-01-01'],
              dtype='datetime64[ns]', freq=None)

df.columns = [level0, level1]

mask = level0.year == 2019
df[(pd.to_datetime('2019-12-01'),'total2019')] = df.loc[:, mask].xs('Bill2', axis=1, level=1).sum(axis=1)
df = df.sort_index(level=0, axis=1)
print (df)
         2019-11-01       2019-12-01                 2020-01-01      
              Bill1 Bill2      Bill1 Bill2 total2019      Bill1 Bill2
A Ind OS          1  1.28          1  1.28      2.56          1  1.28

Последнее, если необходимооригинальный формат datetimes:

level0 = df.columns.get_level_values(0).strftime('%b-%y')
level1 = df.columns.get_level_values(1)

df.columns = [level0, level1]
print (df)
         Nov-19       Dec-19                 Jan-20      
          Bill1 Bill2  Bill1 Bill2 total2019  Bill1 Bill2
A Ind OS      1  1.28      1  1.28      2.56      1  1.28
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...