Python 比较数千个值的更快方法

Python 比较数千个值的更快方法,python,pandas,logic,Python,Pandas,Logic,我有以下数据帧: Price, Volume 100, 45656 101, 67563 103, 755 ... ... 6543, 67567 6544, 7654 Price列中的每个条目都是唯一的,有几千行。目标是确定滚动行范围内的低成交量价格。换句话说,我并不是在试图找出整个数据帧中最低的卷。我在滚动的“窗口”上识别许多低容量行 假设我将滚动窗口设置为50。我要做的是将当前体积值与上面的50个体积值以及下面的50个体积值进行比较。如果当前的体积值是该范围内的最低值,我会将相应的价格保

我有以下数据帧:

Price, Volume
100, 45656
101, 67563
103, 755
...
...
6543, 67567
6544, 7654
Price列中的每个条目都是唯一的,有几千行。目标是确定滚动行范围内的低成交量价格。换句话说,我并不是在试图找出整个数据帧中最低的卷。我在滚动的“窗口”上识别许多低容量行

假设我将滚动窗口设置为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)
滚动窗口=50
总行数=len(df.index)
当前行=滚动窗口
最小_值=[]
当前行<总计行-滚动窗口:
是真的吗
用于比较范围内的行(滚动窗口):
如果vp.iloc[当前行]['Volume']>vp.iloc[当前行-比较行]['Volume']或\
vp.iloc[当前行]['Volume']>vp.iloc[当前行+比较行]['Volume']:
是_=False吗
打破
如果是最小值且vp.iloc[当前行][“价格”]不是最小值:
最小值。追加(vp.iloc[当前行]['Price'])
当前_行+=1
打印(最低价格)
我的问题是,它在处理大型数据帧(数千项)时非常慢。我相信一定有更好的方法来完成我想做的事情,而且更有效。我担心我让算法做的工作比必要的要多,但我还没有想到另一种方法来做


如果有人能提出一种更快/更有效的方法,我将不胜感激。

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

另外,在另一方面,你可以尝试使用一个有序的地图,因为你说价格都是独一无二的。然后,您可以只查看映射的一端(取决于它的排序方式),以提取最小的键/值对。当然,我假设该映射的实现做得很好,但如果它在您的标准库中,则可能是这样


通过这种方式,您可以将列表中的100个值一次输入到地图中,并使其处于全盛时期

从最低点跳49而不是只跳一个会更有意义吗?因为接下来的49个值不能低于刚刚找到的值,如果它是最低的

另外,在另一方面,你可以尝试使用一个有序的地图,因为你说价格都是独一无二的。然后,您可以只查看映射的一端(取决于它的排序方式),以提取最小的键/值对。当然,我假设该映射的实现做得很好,但如果它在您的标准库中,则可能是这样


通过这种方式,您可以将列表中的100个值一次输入到地图中,并使其处于全盛时期

从最低点跳49而不是只跳一个会更有意义吗?因为接下来的49个值不能低于刚刚找到的值,如果它是最低的

另外,在另一方面,你可以尝试使用一个有序的地图,因为你说价格都是独一无二的。然后,您可以只查看映射的一端(取决于它的排序方式),以提取最小的键/值对。当然,我假设该映射的实现做得很好,但如果它在您的标准库中,则可能是这样


通过这种方式,您可以将列表中的100个值一次输入到地图中,并使其处于全盛时期

从最低点跳49而不是只跳一个会更有意义吗?因为接下来的49个值不能低于刚刚找到的值,如果它是最低的

另外,在另一方面,你可以尝试使用一个有序的地图,因为你说价格都是独一无二的。然后,您可以只查看映射的一端(取决于它的排序方式),以提取最小的键/值对。当然,我假设该映射的实现做得很好,但如果它在您的标准库中,则可能是这样


通过这种方式,您可以将列表中的100个值一次输入到地图中,并使其处于全盛时期

步骤1:执行滚动最小值,周期为101个周期(从当前点向上50个周期,向下50个周期)

步骤2:将这些最小值向下移动50,使其居中

步骤3:将体积与移动的最小值进行比较。如果他们匹配,那么这应该是在您的窗口内的最低数量的价格

步骤4:筛选匹配项

第五步:享受额外的几分钟空闲时间

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 

步骤1:执行一个滚动最小值,有101个周期(从当前点向上50个周期,向下50个周期)

步骤2:将这些最小值向下移动50,使其居中

步骤3:将体积与移动的最小值进行比较。如果他们匹配,那么这应该是在您的窗口内的最低数量的价格

步骤4:筛选匹配项

第五步:享受额外的几分钟空闲时间

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 

步骤1:执行一个滚动最小值,有101个周期(从当前点向上50个周期,向下50个周期)

步骤2:将这些最小值向下移动50,使其居中

步骤3:将体积与移动的最小值进行比较。如果他们匹配,那么这应该是在您的窗口内的最低数量的价格

步骤4:筛选匹配项

第五步:享受额外的几分钟空闲时间

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 

步骤1:执行一个滚动最小值,有101个周期(从当前点向上50个周期,向下50个周期)

步骤2:将这些最小值向下移动50,使其居中

第三步:比较容量