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