我有一个名为 idx 的DatetimeIndex:
DatetimeIndex(['2020-10-24 21:00:00+03:00', '2020-10-24 23:00:00+03:00',
'2020-10-25 08:00:00+03:00', '2020-10-26 08:00:00+03:00',
'2020-10-27 13:00:00+03:00', '2020-10-29 07:00:00+03:00',
'2020-10-29 22:00:00+03:00', '2020-10-31 01:00:00+03:00',
'2020-11-01 16:00:00+03:00', '2020-11-03 18:00:00+03:00',
'2020-11-04 20:00:00+03:00', '2020-11-05 17:00:00+03:00'],
dtype='datetime64[ns, Europe/Moscow]', freq=None)
我需要遍历数据帧行以计算每个行的“关闭”列的累积最大值 idx 元素到下一个,然后从以下元素到下一个,依此类推。 通过执行以下操作,效果很好:
for i in np.arange(len(idx)):
signals.loc[idx[i]:, 'close_max'] = signals.loc[idx[i]:, 'close'].cummax(axis=0)
但是迭代数据帧不是一件好事。您能帮忙做到没有for循环吗?
答案 0 :(得分:1)
您可以使用np.searchsorted来找到idx
值在df.index
内的整数索引(注意:即使在{中找不到idx
的值,它也可以工作{1}}。
一旦有了这些整数索引,就可以建立一个适合对df进行分组的df.index
值。然后grp
并应用groupby
。
将它们放在一起:
cummax
验证:
首先,让我们构建一些类似于您的数据进行测试:
ix = np.concatenate(([0], np.searchsorted(df.index, idx), [df.shape[0]]))
grp = np.repeat(ix[:-1], np.diff(ix))
df['close_max'] = df['close'].groupby(grp).cummax()
然后,对您的“信号”计算进行稍加修改,使其没有NaN:
n = 1000
df = pd.DataFrame(
420 + np.round(np.cumsum(np.random.normal(size=n)), 2),
columns=['close'],
index=pd.date_range('2020-10-24', periods=n, freq='h'))
idx = [
pd.Timestamp('2020-10-24') + k * pd.Timedelta('1 hour')
for k in np.cumsum(np.random.randint(1, 48, size=n))
]
idx =[t for t in idx if df.first_valid_index() <= t <= df.last_valid_index()]
idx = pd.DatetimeIndex(idx)