开发者问题收集

替换每组的第一个值

2022-08-30
655

我有一个按 EmpIDDate 排序的 df 。现在我需要将每个 EmpID 第一次出现的 Reason 列更新为值 100。

原文:

员工 ID 日期 原因
123 2022 年 1 月 1 日 0
123 2022 年 1 月 2 日 500
123 01/03 /2022 0
124 01/01/2022 0
124 01/02/2022 800
124 01/03/2022 0

结果:

员工ID 日期 原因
123 2022 年 1 月 1 日 100
123 2022 年 1 月 2 日 500
123 2022 年 1 月 3 日 0
124 2022 年 1 月 1 日 100
124 2022 年 1 月 2 日 800
124 2022 年 1 月 3 日 0

我无论如何都无法接近。更新每个 EmpID 的最小日期并将 Reason 设置为 100 会更容易吗?

我尝试了以下操作但收到错误。

DF.loc[DF.groupby(['EmpID','Date'])['Reason'].head(1), 'Reason'] = '100'

这引发:

KeyError: "None of [Float64Index([ 0.0, 800.0, 0.0, 800.0, 0.0, 800.0, 0.0, 800.0, 0.0,\n 800.0,\n ...\n 800.0, 0.0, 100.0, 800.0, 0.0, 100.0, 800.0, 0.0, 100.0,\n 800.0],\n dtype='float64', name='EEID', length=12769)] are in the [index]"

感谢您的帮助!

3个回答

检查 重复

df.loc[~df['EmpID'].duplicated(),'Reason'] = 100
BENY
2022-08-30

您可以使用 .transform 。只需定义一个返回掩码的函数:除第一个值 True 外,所有值均为 False

使用所有组的组合掩码,您可以选择并替换所需的元素:

def f(s):
    mask = np.full(len(s), False)
    mask[0] = True
    return mask

mask = df.groupby('EmpID')['Reason'].transform(f)
df.loc[mask, 'Reason'] = 100

结果:

EmpID       Date  Reason
0    123 2022-01-01     100
1    123 2022-01-02     500
2    123 2022-01-03       0
3    124 2022-01-01     100
4    124 2022-01-02     800
5    124 2022-01-03       0
Vladimir Fokow
2022-08-30

为了解决这个问题,我们需要确定行号,如果我们得到行号,我们可以根据第一行进行过滤并将原因更改为 100。我们可以使用此函数获取行号 cumcount

data['row_num'] =data.groupby(['EmpID']).cumcount()
data.loc[data.row_num == 0,'Reason'] = 100
data

在此处输入图像描述

Noman
2022-08-30