Как сгруппировать и суммировать, если значение ячейки определенных столбцов соответствует определенным условиям - PullRequest
0 голосов
/ 13 декабря 2018

Я чувствую, что то, что я пытаюсь сделать, довольно просто, но я не могу найти похожий пост здесь.Пожалуйста, дайте мне знать, если мой пост действительно повторяется.

У меня есть данные об инцидентах, связанных с авариями на транспорте.Первые два столбца показывают точное число погибших и травм в результате инцидента, но 3-й и 4-й столбцы (связанные с алкоголем и мобильными телефонами) показывают только двоичные значения: 0 (означает, что нет связи) и 1 (означает, что связано).

Пример данных приведен ниже:

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

    NAME FATAL# INJURY# ALCOHOL CELL
0   City A  5   1   0   0
1   City B  5   1   0   1
2   City A  3   1   1   0
3   City B  3   1   1   0
4   City A  3   0   1   0
5   City B  2   2   0   0

Мне нужно сделать сумму по группам для первых двух столбцов, а затем вычислить сумму FATAL для каждого города, когда ячейка столбца ALCOHOL или CELLPHONEзначение равно 1.

Таким образом, в основном мой желаемый вывод:

   NAME FATAL# INJURY # ALCOHOL FATALCELL FATAL
0   City A  11  2   6   0
1   City B  10  4   3   5

Извините за плохое форматирование, изображения вышеупомянутых фреймов данных, если это помогает понять:

ЧтоУ меня есть

Have

Что я хочу

Want

Я знаю дляпервые два столбца я сделаю df.groupby(['NAME']).['FATAL', 'INJURIES'].sum().А что касается второй части, я могу сделать df1.groupby(['NAME','ALCOHOL_RELATED'])['FATAL_COUNT', 'INJURY_COUNT'].sum(), но тогда я потеряю столбцы общего количества.

Как мне это сделать?

Спасибо.

Ответы [ 3 ]

0 голосов
/ 13 декабря 2018

В одной группе:

df.groupby('NAME').agg(
lambda grp: [grp.loc[grp[col] > 0, 'FATAL#'].sum() if col != 'INJURY#' else grp[col].sum() 
             for col in grp if col != 'FATAL#'])


>>>df

NAME    FATAL#  INJURY# ALCOHOL CELL
A   11  2   6   0
B   10  4   3   5
0 голосов
/ 14 декабря 2018

Вы можете использовать np.where для создания ALCOHOL_FATAL и CELL_FATAL столбцов.

import numpy as np

df['ALCOHOL_FATAL'] = np.where(df['ALCOHOL'] == 1, df['FATAL'], 0)
df['CELL_FATAL'] = np.where(df['CELL'] == 1, df['FATAL'], 0)

После, отбросьте столбцы ALCOHOL и CELL и сгруппируйте данные

df.drop(['ALCOHOL', 'CELL'], axis = 1, inplace=True)
df.groupby('NAME', as_index=False).sum()

    NAME    FATAL # INJURY #    ALCOHOL_FATAL   CELL_FATAL
0   CityA   11  2   6   0
1   CityB   10  4   3   5
0 голосов
/ 13 декабря 2018

Иногда проще присоединить дополнительные серии к вашему фрейму данных, затем groupby:

df = pd.DataFrame({'NAME': ['CityA', 'CityB', 'CityA', 'CityB', 'CityA', 'CityB'],
                   'FATAL#': [5, 5, 3, 3, 3, 2],
                   'INJURY#': [1, 1, 1, 1, 0, 2],
                   'ALCOHOL': [0, 0, 1, 1, 1, 0],
                   'CELL': [0, 1, 0, 0, 0, 0]})

# construct fatals dataframe and join
fatals = df.iloc[:, -2:].mul(df['FATAL#'], axis=0).add_prefix('FATAL_')
df = df.join(fatals)

# define columns to sum and groupby
sum_cols = ['FATAL#', 'INJURY#'] + df.columns[-2:].tolist()
res = df.groupby('NAME')[sum_cols].sum().reset_index()

print(res)

    NAME  FATAL#  INJURY#  FATAL_ALCOHOL  FATAL_CELL
0  CityA      11        2              6           0
1  CityB      10        4              3           5
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...