Вопрос или проблема
Язык: 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
На самом деле, на днях я нашел то, что считаю хорошим решением, пожалуйста, дайте знать, если я пропустил что-то важное.
- Во-первых, я убедился, что матрица полностью отсортирована по дате:
df.sort_values(by=['Дата'], inplace=True)
- Затем я использовал groupby, за которым последовал кумулятивная сумма, чтобы создать переменную, которая будет считать количество случаев до текущего момента в dataframe:
df['Землетрясение_кумулятивная'] = df.groupby(['ID'])['Землетрясение'].cumsum().astype(int)
- Затем я удалил строки с кумулятивной суммой Землетрясений < 0, затем сделал еще одну кумулятивную сумму для других переменных
df = df[df.Землетрясение_кумулятивная >= 1]
df['Пожар_кумулятивная'] = df.groupby(['ID'])['Пожар'].cumsum().astype(int)
df['Ущерб от шторма_кумулятивная'] = df.groupby(['ID'])['Ущерб от шторма'].cumsum().astype(int)
- Наконец, я удалил все дубликаты 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, содержащий записи о людях, датах и бинарных переменных, которые отображают, произошли ли какие-либо события (например, «Землетрясение», «Пожар» и т.д.). Вам нужно выяснить, сколько человек после первого инцидента «Землетрясение» впоследствии подверглись другим положительным событиям, маркированным бинарными переменными.
Шаги реализации
-
Импорт библиотек и создание 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
-
Сортировка данных по дате:
Чтобы убедиться, что события обрабатываются в правильном порядке, сначала отсортируем DataFrame по дате.df = df.sort_values(by='Date')
-
Создание переменной для подсчета первого случая «Землетрясение»:
Используем методgroupby
, чтобы сгруппировать данные по ID и посчитать первое появление «Землетрясение».df['First_Earthquake'] = df.groupby('ID')['Earthquake'].transform(lambda x: x.cumsum().ne(0).cumsum())
-
Фильтрация данных по первому инциденту:
Отфильтруем DataFrame, чтобы оставить только те строки, где произошло хотя бы одно землетрясение.df_after_quake = df[df['First_Earthquake'] > 0]
-
Подсчет положительных событий после первого «Землетрясения»:
Далее, создадим два массива для счетчиков по «Пожар» и «Повреждения от шторма» и подсчитаем количество уникальных 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()
-
Вывод результатов:
Теперь мы можем вывести количество людей, у которых произошли положительные события после первого инцидента «Землетрясение».print(f'Количество людей с пожаром после Землетрясения: {num_fires}') print(f'Количество людей с повреждениями от шторма после Землетрясения: {num_storm_damage}')
Заключение
Ваши данные были успешно сгруппированы, и вы получили информацию о количестве людей, у которых произошли другие положительные события после первого «Землетрясения». Описанный метод является эффективным решением данной задачи и использует основные возможности библиотеки pandas для работы с DataFrame.
Данный подход оптимален для работы с временными рядами и многими событиями. Если у вас возникнут дополнительные вопросы или потребуется более детальная информация, пожалуйста, дайте знать!