我在我的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