Grouping/mapping 使用来自不同 DataFrame 的值作为映射函数 PYTHON PANDAS

Grouping/mapping using values from a different DataFrame as the mapping function PYTHON PANDAS

我有两个 pandas 数据帧。

Trade DataFrame 有不同交易的进入和退出时间列表

Trade#  Entrytimestamp         Exittimestamp 
0 2003-01-02 10:30:00  2003-01-07 14:30:00
1 2003-01-07 13:35:00  2003-01-09 12:30:00
2 2003-01-13 14:30:00  2003-01-16 11:10:00
3 2003-01-14 09:50:00  2003-01-23 13:20:00
4 2003-01-17 13:30:00  2003-01-29 14:30:00

tenmin DataFrame 列出了相关股票的十分钟价格

timestamp             price
2003-01-02 00:00:00     50.12    
2003-01-02 00:10:00     50.15
2003-01-02 00:20:00     50.14
2003-01-02 00:30:00     50.13
2003-01-02 00:40:00     50.14

我想做的是在每笔交易中找到最高价和最低价以获得如下结果:

Trade#  Entrytimestamp         Exittimestamp   IntraTradeMAX  IntraTradeMIN
0 2003-01-02 10:30:00  2003-01-07 14:30:00     60.75          60.40
1 2003-01-07 13:35:00  2003-01-09 12:30:00     70.52          63.26
2 2003-01-13 14:30:00  2003-01-16 11:10:00     69.25          67.52
3 2003-01-14 09:50:00  2003-01-23 13:20:00     62.90          61.00
4 2003-01-17 13:30:00  2003-01-29 14:30:00     67.58          65.15

我知道我只需要按每笔交易的进入和退出时间对十分钟的条文件进行分组并取最大值,但如果不单独遍历每笔交易,我无法弄清楚如何做到这一点。鉴于我的文件有超过 10,000 笔交易,这样做会花费很长时间。关于如何以 pandas 方式执行此操作的任何建议?

如果有帮助,我目前的解决方案(太慢)如下。

def intramax(row):  
    trademax = ten['price'][np.logical_and(ten['timestamp'] > row['Entrytimestamp'], ten['timestamp'] < row['Exittimestamp'])].max()
    return trademax  

trade['IntraTradeMAX'] = trade.apply(intramax, axis=1) 

我相信你可以用更好的算法做得更好,pandas 中可能有一些我没有想到的聪明方法,但是一个非常天真的 numba 实现似乎做得很好

In [110]: @numba.jit(nopython=True)
     ...: def intrastats(entry, exit_, ten_times, ten_prices):
     ...:     N = len(entry)
     ...:     K = len(ten_times)
     ...:     ans = np.zeros((N, 2))
     ...:     for i in range(N):
     ...:         ans[i, 0] = -np.inf
     ...:         ans[i, 1] = np.inf
     ...:         for j in range(K):
     ...:             if ten_times[j] < exit_[i] and ten_times[j] > entry[i]:
     ...:                 ans[i, 0] = max(ten_prices[j], ans[i, 0])
     ...:                 ans[i, 1] = min(ten_prices[j], ans[i, 1])
     ...:     return ans

In [114]: %timeit intrastats(trade['Entrytimestamp'].values.view('int64'), 
                             trade['Exittimestamp'].values.view('int64'), 
                             ten['timestamp'].values.view('int64'),
                             ten['price'].values)
10000 loops, best of 3: 43.1 µs per loop

In [115]: %timeit trade.apply(intramax, axis=1)
100 loops, best of 3: 3.2 ms per loop