Python pandas 分组检查值是否比之前的值改变
Python pandas group by check if value changed then previous value
我对 pandas 库的 groupby 函数有疑问。
我有以下数据框。
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
id
result
date
400001
N
2020-07-03
400001
N
2021-09-09
400001
P
2021-10-27
400002
N
2020-07-03
400003
N
2020-06-30
400003
N
2022-04-27
400004
P
2020-06-30
400004
N
2022-04-27
我需要按列 'id' 分组并提取列 'date' 的值,其中列 'result' 的值发生变化。
如果列 'result' 中的值没有改变,则保留列 'date'.
的第一个值
这是一个例子:
id
date
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')
但是这个功能不太好用。该函数验证与 groupby 选择的列 'id' 的第一个元素的差异。我不需要这个。
你能帮帮我吗?
谢谢
您可以使用重复放置两次来获得您想要的:
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
注意。作为 DataFrame 提供的输入不同于 table。此处显示与 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
我对 pandas 库的 groupby 函数有疑问。 我有以下数据框。
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
id | result | date |
---|---|---|
400001 | N | 2020-07-03 |
400001 | N | 2021-09-09 |
400001 | P | 2021-10-27 |
400002 | N | 2020-07-03 |
400003 | N | 2020-06-30 |
400003 | N | 2022-04-27 |
400004 | P | 2020-06-30 |
400004 | N | 2022-04-27 |
我需要按列 'id' 分组并提取列 'date' 的值,其中列 'result' 的值发生变化。 如果列 'result' 中的值没有改变,则保留列 'date'.
的第一个值这是一个例子:
id | date |
---|---|
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')
但是这个功能不太好用。该函数验证与 groupby 选择的列 'id' 的第一个元素的差异。我不需要这个。
你能帮帮我吗? 谢谢
您可以使用重复放置两次来获得您想要的:
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
注意。作为 DataFrame 提供的输入不同于 table。此处显示与 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