У меня есть большой DataFrame Pandas с несколькими столбцами, включая категорию, подкатегорию, значение и дату. Мне нужно отфильтровать этот DataFrame на основе нескольких условий, а затем агрегировать отфильтрованные результаты. В частности, я хочу:
Filter rows where Category is either "A" or "B".
Further filter these rows to include only those where Value is greater than 10.
Group the filtered data by SubCategory and calculate the sum of Value for each SubCategory.
Sort the results by the summed Value in descending order.
Вот упрощенная версия моего DataFrame:
data = {
'Category': ['A', 'B', 'A', 'C', 'B', 'A'],
'SubCategory': ['X', 'Y', 'X', 'Z', 'X', 'Y'],
'Value': [5, 15, 20, 25, 10, 30],
'Date': pd.to_datetime(['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04', '2023-01-05', '2023-01-06'])
}
df = pd.DataFrame(data)
Для достижения этой цели я попытался объединить несколько методов Pandas, но не уверен, что это наиболее эффективный способ сделать это. Вот мой текущий подход:
filtered_df = df[(df['Category'].isin(['A', 'B'])) & (df['Value'] > 10)]
grouped_df = filtered_df.groupby('SubCategory')['Value'].sum().reset_index()
sorted_df = grouped_df.sort_values(by='Value', ascending=False)
print(sorted_df)
Кажется, этот код работает, но меня беспокоит его эффективность и читаемость, особенно с гораздо большим набором данных.
То, что у вас есть, хорошо: использование масок, как правило, является лучшим методом фильтрации, поскольку они очень эффективны даже для больших наборов данных.
Полагаю, можно было бы заранее выбрать нужные столбцы:
output = (
df.loc[
df.Category.isin(['A', 'B']) # Filter rows where Category is either "A" or "B".
& df.Value.gt(10), # Further filter these rows to include only those where Value is greater than 10.
["SubCategory", "Value"],
]
.groupby("SubCategory", as_index=False).sum() # Group the filtered data by SubCategory and calculate the sum of Value for each SubCategory.
.sort_values(by = "Value", ascending=False) # Sort the results by the summed Value in descending order.
)
Такое форматирование также позволяет оставлять комментарии на каждом этапе~
Я предлагаю выполнить сравнение, если значение> 10 после фильтра данных для категорий (чтобы не проверять значение> 10 для каждого значения исходного кадра данных), например:
out = (
df[df.Category.isin(["A", "B"])]
.query("Value > 10")
.groupby("SubCategory", as_index=False)["Value"]
.sum()
.sort_values(by = "Value", ascending=False)
)
print(out)
Распечатки:
SubCategory Value
1 Y 45
0 X 20