Объединить фрейм данных с двумя уровнями сортировки

#pandas #dataframe #sorting #concatenation

#pandas #фрейм данных #сортировка #объединение

Вопрос:

У меня есть два фрейма данных, один из которых содержит значения (и может быть отсортирован по каждой оси либо по возрастанию, либо по убыванию), а второй, который содержит промежуточные итоги и итоги для каждого индекса отсортированного фрейма данных.

Я хотел бы вставить df_total в конец (или начало) каждого индекса, которому он соответствует, не влияя на начальный порядок значений ( [True, False] на иллюстрации).

 import pandas, numpy

df_values = pandas.DataFrame({"Index1" : [1, 1, 2, 2], "Index2" : ["a", "b", "a", "c"], "Values" : [4, 5, 6, 8]}).set_index(["Index1", "Index2"])
df_totals = pandas.DataFrame({"Index1" : [1, 2, "Grand Total"], "Index2" : ["Total 1", "Total 2", "Grand Total"], "Values" : [9, 14, 23]}).set_index(["Index1", "Index2"])
df_sorted = df_values.sort_values(by=["Index1", "Index2"], ascending = [True, False])

df_to_print = pandas.concat([df_sorted_values,df_totals])

#output

 => df_values = 
                Values
Index1 Index2        
1      b            5
       a            4
2      c            8
       a            6


 => df_totals = 
                          Values
Index1      Index2             
1           Total 1           9
2           Total2           14
Grand Total Grand Total      23



 => df_to_print = 
                          Values
Index1      Index2             
1           b                 5
            a                 4
2           c                 8
            a                 6
1           Total 1           9
2           Total2           14
Grand Total Grand Total      23
 

Желаемый результат :
Для завершения по возрастанию

  => df_to_print = 
                          Values
Index1      Index2             
1           b                 5
            a                 4
            Total 1           9
2           c                 8
            a                 6
            Total2           14
Grand Total Grand Total      23
 

Для завершения по убыванию

  => df_to_print = 
                          Values
Index1      Index2             
Grand Total Grand Total      23
1           Total 1           9
            b                 5
            a                 4
2           Total2           14
            c                 8
            a                 6
 

Ответ №1:

Вы могли бы достичь обоих, добавив новые индексы следующим образом:

 # create new indices values
l3 = df_to_print.reset_index(level=0)['Index1'].isin((1, 2))
l4 = df_to_print['Values']

# set the indices
df_to_print = df_to_print.set_index([l3, l4], append=True)

res = df_to_print.sort_index(level=[2, 0], ascending=[False, True]).reset_index(level=[2, 3], drop=True)

print(res)
 

Вывод (завершение по возрастанию)

                          Values
Index1      Index2             
1           b                 5
            a                 4
            Total 1           9
2           c                 8
            a                 6
            Total 2          14
Grand Total Grand Total      23
 

Для нисходящего выполните:

 res = df_to_print.sort_index(level=[2, 0, 3], ascending=[True, True, False]).reset_index(level=[2, 3], drop=True)

print(res)
 

Вывод (завершение по убыванию)

                          Values
Index1      Index2             
Grand Total Grand Total      23
1           Total 1           9
            b                 5
            a                 4
2           Total 2          14
            c                 8
            a                 6