- Вопрос или проблема
- Ответ или решение
- Как сгруппировать по одному столбцу и найти второе появление значений, превышающих заданный порог
- 1. Подготовка данных
- 2. Создание индикаторной переменной
- 3. Подсчет спикеров давления
- 4. Группировка и нахождение второго появления
- 5. Обработка случаев с одним всплеском
- 6. Создание итогового DataFrame
- Итоговый результат
- Заключение
Вопрос или проблема
Проблема
У меня есть dataframe pandas, который содержит серии данных о людях, номер недели, когда произошел визит, и их систолическое и диастолическое артериальное давление.
ID Weeks Systolic Diastolic
1 9 140 90
1 15 155 97
2 7 140 90
2 8 121 75
2 9 161 93
3 2 160 92
3 20 139 87
3 21 140 95
3 22 145 96
4 5 155 90
4 3 150 97
Что я хочу сделать, так это сгруппировать каждого пациента по ID, отметить, когда у кого-то артериальное давление превысило 140/90, и выяснить, когда артериальное давление пациента превысило это значение во второй раз.
Например, в таблице выше у пациента 3 артериальное давление превышает 140/90 на неделях 2, 21 и 22, поэтому второй случай будет на неделе 21. В результате dataframe будет выглядеть следующим образом:
ID Неделя второго пика
1 15
2 9
3 21
4 5
Что я пробовал
Я могу создать индикаторную переменную, которая показывает, где в dataframe артериальное давление превышает эти значения:
df['High'] = np.where((df['Systolic'] >= 140) & (df['Diastolic'] >= 90) , 1, 0)
Но после этого момента я не уверен, как указать, какая неделя является второй неделей высокого давления для каждого пациента. Я знаю, что я также могу выполнить groupby, чтобы сгруппировать идентификаторы вместе, но я застрял на этом этапе.
Я нашел одно решение благодаря этой теме на SO. В итоге я сделал следующее:
Сначала я создал индикаторную переменную, описанную в вопросе:
df['High'] = np.where((df['Systolic'] >= 140) & (df['Diastolic'] >= 90) , 1, 0)
Затем я сделал кумулятивную сумму, чтобы подсчитать, сколько раз у этого человека было повышение артериального давления к определенной неделе.
df['Prev_highBP'] = df.groupby(['ID'])['High'].cumsum().astype(int)
Затем я отфильтровал людей с высоким давлением, сгруппировав по ID, и создал новую переменную для хранения второй наименьшей недели в этой группе.
grouped = df.loc[testPre['High']==1].groupby(['ID'])['Week']
df['second_spike'] = grouped.transform(lambda x: x.nsmallest(2).max())
Наконец, я исправил случаи, когда было только одно повышение артериального давления, используя переменную кумулятивной суммы, созданную ранее.
df['second_spike'] = np.where((df['Prev_highBP'] != 2) , np.NaN, df['second_spike'])
Тогда я могу получить нужный dataframe, просто удалив дубликаты:
secondSpike = df.drop_duplicates(subset=['ID'], keep='last')
Скорее всего, есть более чистый или эффективный способ сделать это, но на данный момент это кажется рабочим.
Ответ или решение
Как сгруппировать по одному столбцу и найти второе появление значений, превышающих заданный порог
Работа с данными о здоровье — важная задача, требующая внимательного анализа. В вашем случае требуется обработать данные о пациентах, фиксируя их артериальное давление. Рассмотрим, как сгруппировать данные по идентификатору пациента и определить вторую дату, когда артериальное давление превышало указанный порог (140/90 для систолического и диастолического давления).
1. Подготовка данных
Для начала, необходимо импортировать библиотеки и создать DataFrame с вашими данными:
import pandas as pd
import numpy as np
data = {
'ID': [1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4],
'Weeks': [9, 15, 7, 8, 9, 2, 20, 21, 22, 5, 3],
'Systolic': [140, 155, 140, 121, 161, 160, 139, 140, 145, 155, 150],
'Diastolic': [90, 97, 90, 75, 93, 92, 87, 95, 96, 90, 97]
}
df = pd.DataFrame(data)
2. Создание индикаторной переменной
Во-первых, мы создаем индикаторную переменную, чтобы пометить, когда артериальное давление превышает заданный порог:
df['High'] = np.where((df['Systolic'] >= 140) & (df['Diastolic'] >= 90), 1, 0)
3. Подсчет спикеров давления
Далее мы используем функцию кумулятивной суммы для подсчета количества раз, когда у пациента произошло повышение давления:
df['Prev_highBP'] = df.groupby('ID')['High'].cumsum().astype(int)
4. Группировка и нахождение второго появления
Теперь мы можем сгруппировать данные по ID и найти второе появление высокой артериальной нагрузки:
grouped = df[df['High'] == 1].groupby('ID')['Weeks']
df['second_spike'] = grouped.transform(lambda x: x.nsmallest(2).max())
5. Обработка случаев с одним всплеском
После этого нам нужно обработать те случаи, когда у пациентов было менее двух значений выше порога, чтобы избежать вводящих в заблуждение значений:
df['second_spike'] = np.where(df['Prev_highBP'] != 2, np.NaN, df['second_spike'])
6. Создание итогового DataFrame
Наконец, мы можем извлечь итоговый DataFrame, в котором будет только информация о втором всплеске давления для каждого пациента:
secondSpike = df.drop_duplicates(subset=['ID'], keep='last')[['ID', 'second_spike']]
secondSpike.rename(columns={'second_spike': 'Week of Second Spike'}, inplace=True)
Итоговый результат
В результате вы получите DataFrame, представляющий собой ID пациента и неделю, когда произошло второе повышение давления:
ID Week of Second Spike
0 1 15.0
1 2 9.0
2 3 21.0
3 4 5.0
Заключение
Эта процедура позволяет вам эффективно анализировать данные о здоровье пациентов и выявлять значимые временные моменты, такие как второе внезапное повышение артериального давления. Используя комбинацию функций Pandas, вы можете гибко настраивать анализ для получения уникальной аналитики по каждому пациенту.