Как сгруппировать по идентификаторам и подсчитать количество групп с появлением переменной после первой точки?

Вопрос или проблема

Язык: Python 3.8

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

| ID |    Дата  | Землетрясение | Пожар | Ущерб от шторма |
|----|----------|---------------|-------|-----------------|
| 1  |  21/01/21 |     0         |  0    |       0         |
| 2  |  03/02/21 |     1         |  0    |       0         |
| 3  |  04/02/21 |     0         |  1    |       0         |
| 1  |  10/02/21 |     1         |  0    |       0         |
| 1  |  28/02/21 |     0         |  1    |       1         |
| 2  |  05/03/21 |     0         |  0    |       1        | 

Итак, в этом примере, после первого случая землетрясения, один человек пережил пожар, а двое — ущерб от шторма.

Моя проблема в том, что я не могу точно понять, как это сделать. Я думаю, что мне нужно использовать groupby, чтобы сгруппировать все идентификаторы вместе, но я немного застрял после этой точки.

Я не уверен, нужно ли группировать все записи, что создало бы объект группировки, а не dataframe.

Я инициализировал новый dataframe new_df с данными, которые вы упомянули в вашем вопросе, а затем использовал код группировки. Однако я думаю, что вы ищете отсортированную матрицу.

Обратите внимание на код и вывод, упомянутые ниже:

grouped = new_df.groupby("ID")
print(grouped.first())
print("Тип сгруппированного:"+str(type(grouped)))
sorted_df = new_df.sort_values(["ID"], ascending=[1])
print("Тип сортированных значений:"+str(type(sorted_df)))
print(sorted_df)

Вывод:

ID     Дата Землетрясение Пожар Ущерб от шторма
0  1  21/01/21          0    0            0
1  2   03/02/21          1    0            0
2  3   04/02/21          0    1            0
3  1  10/02/21          1    0            0
4  1  28/02/21          0    1            1
5  2   05/03/21          0    0            1
       Дата  Землетрясение  Пожар  Ущерб от шторма
ID                                         
1   21/01/21           0     0             0
2    03/02/21           1     0             0
3    04/02/21           0     1             0
Тип сгруппированного:<class 'pandas.core.groupby.generic.DataFrameGroupBy'>
Тип сортированных значений:<class 'pandas.core.frame.DataFrame'>
  ID     Дата Землетрясение Пожар Ущерб от шторма
0  1  21/01/21          0    0            0
3  1  10/02/21          1    0            0
4  1  28/02/21          0    1            1
1  2   03/02/21          1    0            0
5  2   05/03/21          0    0            1
2  3   04/02/21          0    1            0

На самом деле, на днях я нашел то, что считаю хорошим решением, пожалуйста, дайте знать, если я пропустил что-то важное.

  1. Во-первых, я убедился, что матрица полностью отсортирована по дате:
df.sort_values(by=['Дата'], inplace=True)
  1. Затем я использовал groupby, за которым последовал кумулятивная сумма, чтобы создать переменную, которая будет считать количество случаев до текущего момента в dataframe:

df['Землетрясение_кумулятивная'] = df.groupby(['ID'])['Землетрясение'].cumsum().astype(int)

  1. Затем я удалил строки с кумулятивной суммой Землетрясений < 0, затем сделал еще одну кумулятивную сумму для других переменных
df = df[df.Землетрясение_кумулятивная >= 1]
df['Пожар_кумулятивная'] = df.groupby(['ID'])['Пожар'].cumsum().astype(int)
df['Ущерб от шторма_кумулятивная'] = df.groupby(['ID'])['Ущерб от шторма'].cumsum().astype(int)
  1. Наконец, я удалил все дубликаты ID, сохраняя последний (последнюю дату)
    и подсчитал тех, у кого Пожар и Ущерб от шторма были больше 0.
df.drop_duplicates(subset="ID", keep='last')
dfПожар = df[df["Пожар_кумулятивная"] > 0]
dfШторм = df[df["Ущерб от шторма_кумулятивная"] > 0]
num_rowsПожар = dfПожар.shape[0]
num_rowsШторм = dfШторм.shape[0]

Я не уверен, является ли это самым эффективным методом, но, насколько я могу судить, он работает.

Ответ или решение

Чтобы сгруппировать по ID и подсчитать количество групп после первого события (в вашем случае, после появления переменной «Землетрясение»), вы можете использовать библиотеку pandas в Python. Ниже представлен подробный пошаговый подход, который поможет вам осуществить эту задачу.

Описание задачи

Вы имеете DataFrame, содержащий записи о людях, датах и бинарных переменных, которые отображают, произошли ли какие-либо события (например, «Землетрясение», «Пожар» и т.д.). Вам нужно выяснить, сколько человек после первого инцидента «Землетрясение» впоследствии подверглись другим положительным событиям, маркированным бинарными переменными.

Шаги реализации

  1. Импорт библиотек и создание DataFrame:
    Вам потребуется библиотека pandas. Начнем с ее импорта и загрузки данных в DataFrame.

    import pandas as pd
    
    data = {
       'ID': [1, 2, 3, 1, 1, 2],
       'Date': ['1/21/21', '2/3/21', '2/4/21', '2/10/21', '2/28/21', '3/5/21'],
       'Earthquake': [0, 1, 0, 1, 0, 0],
       'Fire': [0, 0, 1, 0, 1, 0],
       'Storm Damage': [0, 0, 0, 0, 1, 1]
    }
    
    df = pd.DataFrame(data)
    df['Date'] = pd.to_datetime(df['Date'])  # Преобразуем строки в формат datetime
  2. Сортировка данных по дате:
    Чтобы убедиться, что события обрабатываются в правильном порядке, сначала отсортируем DataFrame по дате.

    df = df.sort_values(by='Date')
  3. Создание переменной для подсчета первого случая «Землетрясение»:
    Используем метод groupby, чтобы сгруппировать данные по ID и посчитать первое появление «Землетрясение».

    df['First_Earthquake'] = df.groupby('ID')['Earthquake'].transform(lambda x: x.cumsum().ne(0).cumsum())
  4. Фильтрация данных по первому инциденту:
    Отфильтруем DataFrame, чтобы оставить только те строки, где произошло хотя бы одно землетрясение.

    df_after_quake = df[df['First_Earthquake'] > 0]
  5. Подсчет положительных событий после первого «Землетрясения»:
    Далее, создадим два массива для счетчиков по «Пожар» и «Повреждения от шторма» и подсчитаем количество уникальных ID, где произошли положительные события.

    num_fires = df_after_quake[df_after_quake['Fire'] > 0]['ID'].nunique()
    num_storm_damage = df_after_quake[df_after_quake['Storm Damage'] > 0]['ID'].nunique()
  6. Вывод результатов:
    Теперь мы можем вывести количество людей, у которых произошли положительные события после первого инцидента «Землетрясение».

    print(f'Количество людей с пожаром после Землетрясения: {num_fires}')
    print(f'Количество людей с повреждениями от шторма после Землетрясения: {num_storm_damage}')

Заключение

Ваши данные были успешно сгруппированы, и вы получили информацию о количестве людей, у которых произошли другие положительные события после первого «Землетрясения». Описанный метод является эффективным решением данной задачи и использует основные возможности библиотеки pandas для работы с DataFrame.

Данный подход оптимален для работы с временными рядами и многими событиями. Если у вас возникнут дополнительные вопросы или потребуется более детальная информация, пожалуйста, дайте знать!

Оцените материал
Добавить комментарий

Капча загружается...