熊猫的loc方法动态更改行索引

时间:2020-11-07 10:01:33

标签: python pandas for-loop iteration loc

我有一个名为 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循环吗?

enter image description here

1 个答案:

答案 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)