比较数千个值的更快方法

Faster way to compare thousands of values

我有以下数据框:

Price, Volume
100, 45656
101, 67563
103, 755
...
...
6543, 67567
6544, 7654

价格列中的每个条目都是唯一的,并且有几千行。目标是确定行滚动范围内的低批量价格。换句话说,我并没有试图识别整个数据帧中的最低音量。我在滚动 'window'.

中识别出许多低容量行

假设我将滚动 window 设置为 50。然后我所做的是将当前音量值与上方的 50 个音量值以及下方的 50 个音量值进行比较。如果当前交易量值是该范围内的最低值,我将相应的价格保存到一个单独的列表中。然后向下移动一行,再次比较当前音量值是否小于上下50

我的以下代码可以正确完成此任务:

rolling_window = 50
total_rows = len(df.index)
current_row = rolling_window
smallest_values = []

while current_row < total_rows - rolling_window:
    is_smallest = True
    for comparison_row in range(rolling_window):
        if vp.iloc[current_row]['Volume'] > vp.iloc[current_row -   comparison_row]['Volume'] or \
            vp.iloc[current_row]['Volume'] > vp.iloc[current_row + comparison_row]['Volume']:
            is_smallest = False
            break
    if is_smallest and vp.iloc[current_row]['Price'] not in smallest_values:
        smallest_values.append(vp.iloc[current_row]['Price'])
    current_row += 1

print(smallest_prices)

我的问题是在处理大型数据帧(数千项)时速度非常慢。我确信必须有更好的方法来完成我想做的事情,这样效率更高。我担心我会让算法做的工作比必要的多,但我还没能想到另一种方法。

如果有人能提出 faster/more 有效的方法,我将不胜感激。

跳过 49(从最低)而不是只跳过 49 不是更有意义吗?因为接下来的 49 个值不能低于你刚刚找到的那个,如果它是最低的。

此外,在另一方面,您可以尝试使用有序地图,因为您说价格都是唯一的。然后你可以只看地图的一端(取决于它的排序方式)以拉出最少的 key/value 对。当然,我假设该地图的实现做得很好,但如果它在您的标准库中,它可能是。

这样您就可以一次将列表中的 100 个值输入到地图中,并尽情享受它。

第 1 步:使用 101 个周期(从当前点向上 50 个,向下 50 个)实施滚动最小值。

第 2 步:将这些最小值向下移动 50,使它们居中。

第 3 步:将音量与移动后的最小值进行比较。如果它们匹配,那么这应该是您的 window.

中成交量最低的价格

第 4 步:筛选匹配项。

第 5 步:享受额外的空闲时间!

import pandas as pd
import bumpy as np

df = pd.DataFrame({'price': range(1000), 
                   'volume': np.random.random_integers(0, 500000, 1000)})
df['min_volume'] = pd.rolling_min(df.volume, 101)
df['min_shift'] = df['min_volume'].shift(-50)
df['match'] = df.volume == df.min_shift
>>> df[df.match]
Out[39]: 
     price  volume   min  min_shift match
181    181    4317  4317       4317  True
245    245    4478  4317       4478  True
358    358    1118  1118       1118  True
427    427    7251  1118       7251  True
504    504   10680  7251      10680  True
631    631    1096  1096       1096  True
699    699     277   277        277  True
770    770    2037   277       2037  True
828    828     310   310        310  True
931    931     516   516        516  True

仅获取价格:

df[df.match].price