#python #pandas #dataframe #group-by
#python #панды #фрейм данных #группировать по
Вопрос:
Я хочу объединить следующий dataframe df в соответствии с областью столбца и обитателями столбца. Кроме того, я хочу суммировать значение в области.
import pandas as pd
df = pd.DataFrame({'Region': ['Region1', 'Region1', 'Region1', 'Region2', 'Region2', 'Region2', 'Region3', 'Region3', 'Region4', 'Region4'], 'Inhabitants': [True, False, True, True, False, True, True, True, False, False], 'Area': [60, 20, 20, 60, 30, 10, 50, 50, 50, 50]})
print(df)
Region Inhabitants Area
0 Region1 True 60
1 Region1 False 20
2 Region1 True 20
3 Region2 True 60
4 Region2 False 30
5 Region2 True 10
6 Region3 True 50
7 Region3 True 50
8 Region4 False 50
9 Region4 False 50
Это сработало с этим кодом:
df = df.groupby(['Region', 'Inhabitants'], as_index=False)['Area'].sum()
print(df)
Region Inhabitants Area
0 Region1 False 20
1 Region1 True 80
2 Region2 False 30
3 Region2 True 70
4 Region3 True 100
5 Region4 False 100
В конце я хочу решить, равна ли сумма истинных областей для каждого региона> = 80. Это должно быть указано в добавленном столбце Region_ok как True, если истинная площадь для каждого региона > = 80 или False, если нет. Это снова должно быть сгруппировано по регионам. Результат должен выглядеть следующим образом:
Region Region_ok
0 Region1 True
1 Region2 False
2 Region3 True
3 Region4 False
Я попробовал несколько вещей с groupby, но не могу найти подходящего решения.
Ответ №1:
Самое простое решение — заменить Area
0
, если False в Inhabitants
by Series.where
, затем агрегировать сумму, сравнить для большего или равного и последнего преобразования Series
в DataFrame
:
df2 = (df['Area'].where(df['Inhabitants'], 0)
.groupby(df['Region'])
.sum()
.ge(80)
.reset_index(name='Region_ok'))
print(df2)
Region Region_ok
0 Region1 True
1 Region2 False
2 Region3 True
3 Region4 False
Вы можете работать с агрегированным фреймом данных — фильтровать по большему 80
по Series.gt
и связывать amp;
с логическим столбцом и последним тестом, если хотя бы одно значение совпадает по GroupBy.any
:
df1 = df.groupby(['Region', 'Inhabitants'], as_index=False)['Area'].sum()
m = df1['Area'].ge(80) amp; df1['Inhabitants']
df2 = m.groupby(df1['Region']).any().reset_index(name='Region_ok')
print(df2)
Region Region_ok
0 Region1 True
1 Region2 False
2 Region3 True
3 Region4 False
Аналогичная идея, но для работы с исходными данными, заключается в использовании GroupBy.transform
sum
и фильтрации в исходном фрейме данных:
s = df.groupby(['Region', 'Inhabitants'])['Area'].transform('sum')
m = s.ge(80) amp; df['Inhabitants']
df2 = m.groupby(df['Region']).any().reset_index(name='Region_ok')
print(df2)
Region Region_ok
0 Region1 True
1 Region2 False
2 Region3 True
3 Region4 False
Следующее решение сначала фильтрует только True
s строк и агрегирует sum
только по Region
:
s = df[df['Inhabitants']].groupby('Region')['Area'].sum()
df2 = (s.ge(80)
.reindex(df['Region'].unique(), fill_value=False)
.reset_index(name='Region_ok'))
print(df2)
Region Region_ok
0 Region1 True
1 Region2 False
2 Region3 True
3 Region4 False
Комментарии:
1. спасибо, все варианты решения работают отлично