У меня проблема с функцией groupby библиотеки pandas. У меня есть следующий фрейм данных.
d = {'id': [400001, 400001, 400001, 400002, 400003, 400003, 400004, 400004], 'result': ['P','N','N','N','N','N','N','P'], 'date':['27/10/2021','09/09/2021','03/07/2020','03/07/2020','30/06/2020','27/04/2022','27/04/2022','30/06/2020']}
df = pd.DataFrame(data=d)
df
я бы | результат | дата |
---|---|---|
400001 | Н | 2020-07-03 |
400001 | Н | 2021-09-09 |
400001 | п | 2021-10-27 |
400002 | Н | 2020-07-03 |
400003 | Н | 2020-06-30 |
400003 | Н | 2022-04-27 |
400004 | п | 2020-06-30 |
400004 | Н | 2022-04-27 |
Мне нужно сгруппировать по столбцу «id» и извлечь значение столбца «дата», где значение столбца «результат» изменяется. Если значение в столбце «результат» не меняется, сохраните первое значение столбца «дата».
Это пример:
я бы | дата |
---|---|
400001 | 2021-10-27 |
400002 | 2020-07-03 |
400003 | 2020-06-30 |
400004 | 2022-04-27 |
Я пробовал это:
df['change'] = np.where(df.groupby('id').esito.apply(lambda x:x!=x.iloc[0]),'Y','N')
но функция работает не так хорошо. Функция проверяет разницу с первым элементом столбца 'id' выбора groupby. Мне это не нужно.
Можете вы помочь мне? Спасибо
Да, это возможно. Вам нужно сохранить самое последнее значение
Можете ли вы дважды проверить предоставленный DataFrame? Не соответствует таблице.
Да, ты прав. Распечатанная таблица правильная.
Вы можете использовать дубликаты дважды, чтобы получить то, что хотите:
import pandas as pd
d = {'id': [400001, 400001, 400001, 400002, 400003, 400003, 400004, 400004],
'result': ['N', 'N', 'P', 'N', 'N', 'N', 'P', 'N'],
'date': ['27/10/2021', '09/09/2021', '03/07/2020', '03/07/2020', '30/06/2020', '27/04/2022', '27/04/2022',
'30/06/2020']}
df = pd.DataFrame(data=d)
df.drop_duplicates(subset=['id', 'result'], keep='first', inplace=True)
df.drop_duplicates(subset=['id'], keep='last', inplace=True)
print(df)
Выход:
id result date
2 400001 P 03/07/2020
3 400002 N 03/07/2020
4 400003 N 30/06/2020
7 400004 N 30/06/2020
Обратите внимание, что вывод в вашем вопросе может быть неправильным в зависимости от ваших требований.
Вы можете вычислить cumsum
логических значений, идентифицирующих изменения. Затем получите максимальный индекс:
idx = (df.groupby('id')['result']
.apply(lambda s: s.ne(s.shift())
.cumsum()
.idxmax()
)
)
df.loc[idx]
Выход:
id result date
1 400001 N 09/09/2021
3 400002 N 03/07/2020
4 400003 N 30/06/2020
7 400004 P 30/06/2020
NB. Ввод, предоставленный как DataFrame, отличается от ввода в виде таблицы. Здесь показан вывод, соответствующий DataFrame.
При необходимости сначала отсортируйте даты:
idx = (df.sort_values(by=['id', 'date'])
.groupby('id')['result']
.apply(lambda s: s.ne(s.shift())
.cumsum()
.idxmax()
)
)
df.loc[idx]
Выход:
id result date
0 400001 P 27/10/2021
3 400002 N 03/07/2020
5 400003 N 27/04/2022
7 400004 P 30/06/2020
Хорошо спасибо. Но в случае «id» = 400003, когда значение столбца «результат» не меняется, мы должны сохранить первое значение «дата». Я не знаю, ясно ли я выразился.
Да, и это первая строка в предоставленном DataFrame
Тот самый: d = {'id': [400001, 400001, 400001, 400002, 400003, 400003, 400004, 400004], 'result': ['P','N','N','N','N','N','N','P'], 'date':['27/10/2021','09/09/2021','03/07/2020','03/07/2020','30/06/2020','27/04/2022','27/04/2022','30/06/2020']} ; df = pd.DataFrame(data=d)
хорошо, с первым значением я имею в виду менее поздние. Так что сортировать значения правильно.
Может ли значение меняться много раз для каждого идентификатора? Что должно произойти?