我有以下DataFrame df
,可以按如下方式创建:
date_today = datetime.now().date()
days = pd.date_range(date_today, date_today + timedelta(19), freq='D')
x = np.arange(0,2*np.pi,0.1*np.pi) # start,stop,step
y = np.sin(x)
df = pd.DataFrame({'dates': days, 'vals': y, 'is_hit': abs(y)>0.9})
df = df.set_index('dates')
看起来像这样:
is_hit vals
dates
2019-03-27 False 0.000000e+00
2019-03-28 False 3.090170e-01
2019-03-29 False 5.877853e-01
2019-03-30 False 8.090170e-01
2019-03-31 True 9.510565e-01
2019-04-01 True 1.000000e+00
2019-04-02 True 9.510565e-01
2019-04-03 False 8.090170e-01
2019-04-04 False 5.877853e-01
2019-04-05 False 3.090170e-01
2019-04-06 False 1.224647e-16
2019-04-07 False -3.090170e-01
2019-04-08 False -5.877853e-01
2019-04-09 False -8.090170e-01
2019-04-10 True -9.510565e-01
2019-04-11 True -1.000000e+00
2019-04-12 True -9.510565e-01
2019-04-13 False -8.090170e-01
2019-04-14 False -5.877853e-01
2019-04-15 False -3.090170e-01
我想标记is_hit
条件为True
的行,以使预期的新列hit_first
为:
is_hit vals hit_first
dates
2019-03-27 False 0.000000e+00 False
2019-03-28 False 3.090170e-01 False
2019-03-29 False 5.877853e-01 False
2019-03-30 False 8.090170e-01 False
2019-03-31 True 9.510565e-01 True
2019-04-01 True 1.000000e+00 False
2019-04-02 True 9.510565e-01 False
2019-04-03 False 8.090170e-01 False
2019-04-04 False 5.877853e-01 False
2019-04-05 False 3.090170e-01 False
2019-04-06 False 1.224647e-16 False
2019-04-07 False -3.090170e-01 False
2019-04-08 False -5.877853e-01 False
2019-04-09 False -8.090170e-01 False
2019-04-10 True -9.510565e-01 True
2019-04-11 True -1.000000e+00 False
2019-04-12 True -9.510565e-01 False
2019-04-13 False -8.090170e-01 False
2019-04-14 False -5.877853e-01 False
2019-04-15 False -3.090170e-01 False
如何创建此hit_first
列?
答案 0 :(得分:11)
我的建议:
df['hit_first'] = df['is_hit'] & (~df['is_hit']).shift(1)
答案 1 :(得分:3)
将与&
链接的Series.shift
用于按位AND
:
df['hit_first'] = df['is_hit'].ne(df['is_hit'].shift()) & df['is_hit']
print (df)
vals is_hit hit_first
dates
2019-03-27 0.000000e+00 False False
2019-03-28 3.090170e-01 False False
2019-03-29 5.877853e-01 False False
2019-03-30 8.090170e-01 False False
2019-03-31 9.510565e-01 True True
2019-04-01 1.000000e+00 True False
2019-04-02 9.510565e-01 True False
2019-04-03 8.090170e-01 False False
2019-04-04 5.877853e-01 False False
2019-04-05 3.090170e-01 False False
2019-04-06 1.224647e-16 False False
2019-04-07 -3.090170e-01 False False
2019-04-08 -5.877853e-01 False False
2019-04-09 -8.090170e-01 False False
2019-04-10 -9.510565e-01 True True
2019-04-11 -1.000000e+00 True False
2019-04-12 -9.510565e-01 True False
2019-04-13 -8.090170e-01 False False
2019-04-14 -5.877853e-01 False False
2019-04-15 -3.090170e-01 False False
答案 2 :(得分:3)
我也认为您可以这样做:
df['is_hit'].astype(int).diff() == 1
输出:
dates
2019-03-27 False
2019-03-28 False
2019-03-29 False
2019-03-30 False
2019-03-31 True
2019-04-01 False
2019-04-02 False
2019-04-03 False
2019-04-04 False
2019-04-05 False
2019-04-06 False
2019-04-07 False
2019-04-08 False
2019-04-09 False
2019-04-10 True
2019-04-11 False
2019-04-12 False
2019-04-13 False
2019-04-14 False
2019-04-15 False
Name: is_hit, dtype: bool
时间:
%timeit df['is_hit'] & (~df['is_hit']).shift(1)
1.13 ms ± 5.63 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit df['is_hit'].ne(df['is_hit'].shift()) & df['is_hit']
908 µs ± 9.53 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit df['is_hit'].astype(int).diff() == 1
689 µs ± 8.24 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
答案 3 :(得分:-1)
这也可以通过使用序列之间的简单差异以及将序列移位1个周期来实现:
df['hit_first'] = df['is_hit']-df['is_hit'].shift()==1