У меня есть очень большой набор данных под названием bin_df.
Используя pandas и следующий код, я присвоил каждой группе промежуточный итог «Итого»:
bin_df = df[df["category"].isin(model.BINARY_CATEGORY_VALUES)]
bin_category_mime_type_count_df = (
bin_df.groupby(["category", "mime_type"])["mime_type"]
.count()
.reset_index(name = "Count")
)
Вывод из bin_category_mime_type_count_df:
category mime_type Count
1 application/x-executable 19
1 application/x-pie-executable 395
1 application/x-sharedlib 1
2 application/x-sharedlib 755
3 application/x-sharedlib 1
6 application/x-object 129
Затем:
bin_category_total_count_df = (
bin_category_mime_type_count_df.groupby(["category", "mime_type"])[
"Count"
]
.sum()
.unstack()
)
bin_category_total_count_df = (
bin_category_total_count_df.assign(
Total=bin_category_total_count_df.sum(1)
)
.stack()
.to_frame("Count")
)
bin_category_total_count_df["Count"] = (
bin_category_total_count_df["Count"].astype("Int64").fillna(0)
)
В результате получается следующее (по умолчанию оно отсортировано по категориям):
Count
category mime_type
1 application/x-executable 19
application/x-pie-executable 395
application/x-sharedlib 1
Total 415
2 application/x-sharedlib 755
Total 755
3 application/x-sharedlib 1
Total 1
6 application/x-object 129
Total 129
Я хотел бы, чтобы он был отсортирован по «Итогу», а затем внутри категории я хотел бы, чтобы он был отсортирован по количеству mime_type:
Count
category mime_type
2 application/x-sharedlib 755
Total 755
1 application/x-pie-executable 395
application/x-executable 19
application/x-sharedlib 1
Total 415
6 application/x-object 129
Total 129
3 application/x-sharedlib 1
Total 1
На какую функцию мне следует обратить внимание, чтобы получить желаемый результат?
Пример кода
import pandas as pd
data = {'Count': {(1, 'application/x-executable'): 19, (1, 'application/x-pie-executable'): 395, (1, 'application/x-sharedlib'): 1, (1, 'Total'): 415, (2, 'application/x-sharedlib'): 755, (2, 'Total'): 755, (3, 'application/x-sharedlib'): 1, (3, 'Total'): 1, (6, 'application/x-object'): 129, (6, 'Total'): 129}}
df = pd.DataFrame(data).rename_axis(['category', 'mime_type'])
Код
out = df.sort_values(
'Count',
ascending=False,
key=lambda x: list(
zip(
df.groupby(level=0)['Count'].transform(sum),
x.mask(df.index.get_level_values(1) == 'Total', -1)
)
)
)
вне
Приняв bin_category_mime_type_count_df
в качестве входных данных, я бы переосмыслил способ вычисления итоговых значений (промежуточный результат без суммирования неэффективен). Вместо этого выполните одну команду groupby.sum и отсортируйте итоговую сумму, а затем используйте эту информацию для изменения порядка категорий (с помощью sort_values + Категориальная ) после шага concat для объединения подсчетов и итоговых значений:
# get the sum per group
# sort the categories by total
tmp = (
bin_category_total_count_df.groupby('category')[['Count']]
.sum()
.sort_values(by='Count', ascending=False)
.assign(mime_type='Total').reset_index()
)
# combine the counts and Total
# sort by category
out = (pd.concat([bin_category_mime_type_count_df, tmp])
.sort_values(by='category', kind='stable',
key=lambda x: pd.Categorical(x, categories=tmp['category'],
ordered=True),
ignore_index=True
)
)
Вариант для второго шага:
out = (pd.concat([bin_category_mime_type_count_df, tmp])
.astype({'category': pd.CategoricalDtype(categories=tmp['category'],
ordered=True)})
.sort_values(by='category', kind='stable', ignore_index=True)
)
Выход:
category mime_type Count
0 2 application/x-sharedlib 755
1 2 Total 755
2 1 application/x-executable 19
3 1 application/x-pie-executable 395
4 1 application/x-sharedlib 1
5 1 Total 415
6 6 application/x-object 129
7 6 Total 129
8 3 application/x-sharedlib 1
9 3 Total 1
Промежуточный tmp
:
category Count mime_type
0 2 755 Total
1 1 415 Total
2 6 129 Total
3 3 1 Total
@Шарлотта, это не так, код работает как положено. Это была моя ошибка при копировании результатов.
Промежуточные итоги не должны включаться в итоговую сумму, они являются промежуточными итогами группы. Например, 1510 должно быть 755. Спасибо за пример sort_value, ключевого аргумента.