【问题标题】:Numpy, how can i index an array, to keep items that are smaller than the previous and next 5 items following them?Numpy,我如何索引一个数组,以保留小于前一个和下一个 5 个项目的项目?
【发布时间】:2021-07-07 22:08:09
【问题描述】:

我正在制定一个使用支撑位和阻力位的交易策略。我找到这些的方法之一是搜索最大值/最小值(高于/低于前一个和下一个 5 个价格的价格)。

我有一系列平滑的收盘价,我首先尝试使用 for 循环找到它们:

def find_max_min(smoothed_prices) # smoothed_prices = np.array([1.873,...])
    avg_delta = np.diff(smoothed_prices).mean()
    maximas = []
    minimas = []
    for index in range(len(smoothed_prices)):
        if index < 5 or index > len(smoothed_prices) - 6:
            continue

        current_value = smoothed_prices[index]
        previous_points = smoothed_prices[index - 5:index]
        next_points = smoothed_prices [index+1:index+6]

        previous_are_higher = all(x > current_value for x in previous_points)
        next_are_higher = all(x > current_value for x in next_points)

        previous_are_smaller = all(x < current_value for x in previous_points)
        next_are_smaller = all(x < current_value for x in next_points)

        previous_delta_is_enough = abs(previous[0] - current_value) > avg_delta 
        next_delta_is_enough = abs(next_points[-1] - current_value) > avg_delta
        delta_is_enough = previous_delta_is_enough and next_delta_is_enough  

        if previous_are_higher and next_are_higher and delta_is_enough:
            minimas.append(current_value)

        elif previous_are_higher and next_are_higher and delta_is_enough:
            maximas.append(current_value)

        else:
            continue

        return maximas, minimas

(这不是我使用的实际代码,因为我删除了它,这可能不起作用,但就是这样)

所以这段代码可以找到最大值和最小值,但它太慢了,我需要在巨大的数组上每秒多次使用该函数。

我的问题是:是否有可能以类似的方式使用 numpy 掩码:

smoothed_prices = s
minimas = s[all(x > s[index] for x in s[index-5:index]) and all(x > s[index] for x in s[index+1:index+6])]
maximas = ...

或者你知道我可以用另一种有效的 numpy 方式来实现它吗?

【问题讨论】:

    标签: python numpy indexing


    【解决方案1】:

    我想到了一个办法,应该比你介绍的 for 循环快,但是它占用更多的内存。简单地说,它创建了一个窗口的中间矩阵,然后它只是获取每个窗口的最大值和最小值:

    def find_max_min(arr, win_pad_size=5):
        windows = np.zeros((len(arr) - 2 * win_pad_size, 2 * win_pad_size + 1))
        for i in range(2 * win_pad_size + 1):
            windows[:, i] = arr[i:i+windows.shape[0]]
        return windows.max(axis=1), windows.min(axis=1)
    

    编辑:我找到了一种更快的方法来计算来自Split Python sequence into subsequences 的子序列(我称之为 windows)。它不会使用更多内存,而是创建数组的视图。

    def subsequences(ts, window):
        shape = (ts.size - window + 1, window)
        strides = ts.strides * 2
        return np.lib.stride_tricks.as_strided(ts, shape=shape, strides=strides)
    
    def find_max_min(arr, win_pad_size=5):
        windows = subsequences(arr, 2 * win_pad_size + 1)
        return windows.max(axis=1), windows.min(axis=1)
    

    【讨论】:

      【解决方案2】:

      您可以通过以下方式轻松完成:

      from skimage.util import view_as_windows
      a = smoothed_prices[4:-5]
      a[a == view_as_windows(smoothed_prices, (10)).min(-1)]
      

      请注意,由于您正在查看索引的 +/- 5 范围内的最小值,它们可能位于数组的索引 [4:-5] 中。

      【讨论】:

        猜你喜欢
        • 2020-12-09
        • 2023-01-09
        • 1970-01-01
        • 1970-01-01
        • 2020-09-24
        • 2015-01-12
        • 2015-12-29
        • 1970-01-01
        相关资源
        最近更新 更多