是否有比apply()更有效的方法来检查和替换Pandas数据框中的行值?



我在我的Dataframe上运行下面的函数,如果日期与有警告('Y')的日期相同,则列'tdelta'中的数字应替换为250。

这是原来的df:

reset category       date     id  group  tdelta  tdelta reverse
6      N      low 2021-06-23  16860    2.0    33.0             0.0
5      Y      low 2021-05-21  16860    2.0     0.0           -33.0
10     N   medium 2020-12-06   1111    1.0    29.0             0.0
1      Y      low 2020-12-06  16860    1.0     0.0             0.0
2      N      low 2020-12-06  16860    1.0     0.0             0.0
8      Y   medium 2020-11-07   1111    1.0     0.0           -29.0
9      N   medium 2020-11-07   1111    1.0     0.0           -29.0
4      N      low 2019-11-08  16860    0.0    65.0             0.0
3      N      low 2019-09-07  16860    0.0     3.0           -62.0
7      N   medium 2019-09-04   1111    0.0     0.0             0.0

这是代码和结果输出:

def format(row):
r_dates = df[(df['id'] == row['id']) & (df['reset'] == 'Y')]['date']
r_dates = r_dates.tolist()
if row['date'] in r_dates:
val = 250
else:
val = row['tdelta']

return val

df['tdelta'] = df.apply(format, axis =1)
print(df)
reset category       date     id  group  tdelta  tdelta reverse
6      N      low 2021-06-23  16860    2.0    33.0             0.0
5      Y      low 2021-05-21  16860    2.0   250.0           -33.0
10     N   medium 2020-12-06   1111    1.0    29.0             0.0
1      Y      low 2020-12-06  16860    1.0   250.0             0.0
2      N      low 2020-12-06  16860    1.0   250.0             0.0
8      Y   medium 2020-11-07   1111    1.0   250.0           -29.0
9      N   medium 2020-11-07   1111    1.0   250.0           -29.0
4      N      low 2019-11-08  16860    0.0    65.0             0.0
3      N      low 2019-09-07  16860    0.0     3.0           -62.0
7      N   medium 2019-09-04   1111    0.0     0.0             0.0
0      N      low 2019-09-04  16860    0.0     0.0           -65.0

然而,当我将此应用于更大的数据集(大约。20万行),那么它似乎需要很长时间。我想知道是否有一种更有效的方法来完成上面的代码。

编辑:

我已经更改了列"id"中的一些id。以反映不同id的情况

id列也必须考虑在内,因为在更大的数据集(id列中有不同的id)中,这些id有唯一的重置日期。

因此,我需要计算所有的"y"对于id。

问题是会有其他id可能与另一个id的警报落入相同的日期,然而,这些不应该改变,如第三行(索引10)所示,其中日期与id 16860相同,但保持不变,因为该id的警报不在该日期。

尝试后:

r_id = df[df['reset'] == 'Y']['id']
r_dates = df[df['reset'] == 'Y']['date']
df['tdelta'] = np.where((df['id'].isin(r_id) & df['date'].isin(r_dates)),250,df['tdelta'])

下面显示了一个错误的输出:

reset category       date     id  group  tdelta  tdelta reverse
6      N      low 2021-06-23  16860    2.0    33.0             0.0
5      Y      low 2021-05-21  16860    2.0   250.0           -33.0
10     N   medium 2020-12-06   1111    1.0   250.0             0.0
1      Y      low 2020-12-06  16860    1.0   250.0             0.0
2      N      low 2020-12-06  16860    1.0   250.0             0.0
8      Y   medium 2020-11-07   1111    1.0   250.0           -29.0
9      N   medium 2020-11-07   1111    1.0   250.0           -29.0
4      N      low 2019-11-08  16860    0.0    65.0             0.0
3      N      low 2019-09-07  16860    0.0     3.0           -62.0
7      N   medium 2019-09-04   1111    0.0     0.0             0.0
0      N      low 2019-09-04  16860    0.0     0.0           -65.0

申请时间:

In: %timeit df['tdelta'] = df.apply(format, axis =1)
Out: 11.3 ms ± 470 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

上次我测量应用时没有

df['id'] == row['id']

我的错,现在我明白它是干什么用的了。

为了更快,我们需要2个列表:

r_id = df[df['reset'] == 'Y']['id']
r_dates = df[df['reset'] == 'Y']['date']

更新numpy.where:

df['tdelta'] = np.where((df['id'].isin(r_id) & df['date'].isin(r_dates)),250,df['tdelta'])

生成这些列表的时间大约是np的一半。Where time for each, all together(生成列表和numpy Where:)

1.63 ms ± 110 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

df例子:

df = pd.DataFrame({'id':[223, 227, 2214, 2215, 226, 2215, 2215, 238, 253],
'reset':['N','Y','N','Y','N','Y','N','Y','Y'],
'date':[3, 7, 15, 16, 15, 15, 15, 38, 53],
'tdelta':[3, 7, 14, 15, 17, 26, 32, 38, 53]})
r_id = df[df['reset'] == 'Y']['id']
r_dates = df[df['reset'] == 'Y']['date']
df['tdelta'] = np.where((df['id'].isin(r_id) & df['date'].isin(r_dates)),250,df['tdelta'])
df

:

id  reset   date    tdelta
0   223     N   3       3
1   227     Y   7       250
2   2214    N   15      14
3   2215    Y   16      250
4   226     N   15      17
5   2215    Y   15      250
6   2215    N   15      250
7   238     Y   38      250
8   253     Y   53      250

最新更新