Numpy:如何检查一个数字是否是前K个数字中的最小值/最大值?

huangapple go评论96阅读模式
英文:

Numpy: How to check if a number is the minimum/maximum among the previous K numbers?

问题

我尝试自动化一个交易策略,该策略应在当前价格是前k个价格中的最小值/最大值时进入/退出多头头寸。

结果应包含以下内容:如果当前数字是前k个数字中的最大值,则为1,如果是最小值则为-1,如果没有条件成立则为0。

例如,如果k = 3,numpy数组 = [1, 2, 3, 2, 1, 6],结果应该是一个类似的数组:
[0, 0, 1, 0, -1, 1]。

英文:

I'm trying to automate a trading strategy which should enter/exit a long position when the current price is the minimum/maximum among the previous k prices.

The result should contain 1 if the current number is maximum among previous k numbers, -1 if it is the minimum and 0 if none of the conditions are true.

For example if k = 3 and the numpyp array = [1, 2, 3, 2, 1, 6], the result should be an array like:
[0, 0, 1, 0, -1, 1].

I tried the numpy's max function but don't know how to take into account the previous k numbers instead of fixed index and how to switch to default condition for the first k - 1 numbers which should be 0 since there are not k number available to compare them with.

答案1

得分: 4

import pandas as pd
array = [1, 2, 3, 2, 1, 6]
df = pd.DataFrame(array)
df['rolling_max'] = df[0].rolling(3).max()
df['rolling_min'] = df[0].rolling(3).min()
df['result'] = df.apply(lambda row: 1 if row[0] == row['rolling_max'] else (-1 if row[0] == row['rolling_min'] else 0), axis=1)

英文:

I will use Pandas

  1. import pandas as pd
  2. array = [1, 2, 3, 2, 1, 6]
  3. df = pd.DataFrame(array)
  4. df['rolling_max'] = df[0].rolling(3).max()
  5. df['rolling_min'] = df[0].rolling(3).min()
  6. df['result'] = df.apply(lambda row: 1 if row[0] == row['rolling_max'] else (-1 if row[0] == row['rolling_min'] else 0), axis=1)

答案2

得分: 1

以下是使用numpy的解决方案,使用了numpy.lib.stride_tricks.sliding_window_view介绍的方法,该方法在版本1.20.0中引入。

注意,这个解决方案(与@Hanwei Tang提出的解决方案一样)并不完全符合您的要求,因为在第二个窗口([2, 3, 2])中,2是最小值,因此返回-1而不是您要求的零。但也许您应该重新考虑是否真的希望在第二个窗口中得到零,还是-1。

编辑:如果一个窗口只包含相同的数字,即最小值和最大值相同,这个方法返回零。

  1. import numpy as np
  2. def rolling_max(a, wsize):
  3. windows = np.lib.stride_tricks.sliding_window_view(a, wsize)
  4. return np.max(windows, axis=-1)
  5. def rolling_min(a, wsize):
  6. windows = np.lib.stride_tricks.sliding_window_view(a, wsize)
  7. return np.min(windows, axis=-1)
  8. def check_prize(a, wsize):
  9. rmax = rolling_max(a, wsize)
  10. rmin = rolling_min(a, wsize)
  11. ismax = np.where(a[wsize-1:] == rmax, 1, 0)
  12. ismin = np.where(a[wsize-1:] == rmin, -1, 0)
  13. result = np.zeros_like(a)
  14. result[wsize-1:] = ismax + ismin
  15. return result
  16. a = np.array([1, 2, 3, 2, 1, 6])
  17. check_prize(a, wsize=3)
  18. # 输出:
  19. # array([ 0, 0, 1, -1, -1, 1])
  20. b = np.array([1, 2, 4, 3, 1, 6])
  21. check_prize(b, wsize=3)
  22. # 输出:
  23. # array([ 0, 0, 1, 0, -1, 1])
  24. c = np.array([1, 2, 2, 2, 1, 6])
  25. check_prize(c, wsize=3)
  26. # 输出:
  27. # array([ 0, 0, 1, 0, -1, 1])
英文:

Here is a solution with numpy using numpy.lib.stride_tricks.sliding_window_view, which was introduced in version 1.20.0.

Note that this solution (like the one proposed by @Hanwei Tang) does not exactly yield the result you was looking for, because in the second window ([2, 3, 2]) 2 is the minimum value and thus a -1 is returned instead of zero (what you requested). But maybe you should rethink whether you really want a zero for the second window or a -1.

EDIT: If a windows only contains same numbers, i.e. the minimum and maximum are the same, this method returns a zero.

  1. import numpy as np
  2. def rolling_max(a, wsize):
  3. windows = np.lib.stride_tricks.sliding_window_view(a, wsize)
  4. return np.max(windows, axis=-1)
  5. def rolling_min(a, wsize):
  6. windows = np.lib.stride_tricks.sliding_window_view(a, wsize)
  7. return np.min(windows, axis=-1)
  8. def check_prize(a, wsize):
  9. rmax = rolling_max(a, wsize)
  10. rmin = rolling_min(a, wsize)
  11. ismax = np.where(a[wsize-1:] == rmax, 1, 0)
  12. ismin = np.where(a[wsize-1:] == rmin, -1, 0)
  13. result = np.zeros_like(a)
  14. result[wsize-1:] = ismax + ismin
  15. return result
  16. a = np.array([1, 2, 3, 2, 1, 6])
  17. check_prize(a, wsize=3)
  18. # Output:
  19. # array([ 0, 0, 1, -1, -1, 1])
  20. b = np.array([1, 2, 4, 3, 1, 6])
  21. check_prize(b, wsize=3)
  22. # Output:
  23. # array([ 0, 0, 1, 0, -1, 1])
  24. c = np.array([1, 2, 2, 2, 1, 6])
  25. check_prize(c, wsize=3)
  26. # Output:
  27. # array([ 0, 0, 1, 0, -1, 1])

答案3

得分: 1

以下是翻译好的部分:

"Another approach using sliding_window_view with pad:"

  1. from numpy.lib.stride_tricks import sliding_window_view as swv
  2. k = 3
  3. a = np.array([1, 2, 3, 2, 1, 6])
  4. # create sliding window
  5. v = swv(np.pad(a.astype(float), (k-1, 0), constant_values=np.nan), k)
  6. # compare each element to min/max of sliding window
  7. out = np.select([np.max(v, 1)==a, np.min(v, 1)==a], [1, -1], 0)

Output: array([ 0, 0, 1, -1, -1, 1])

英文:

Another approach using sliding_window_view with pad:

  1. from numpy.lib.stride_tricks import sliding_window_view as swv
  2. k = 3
  3. a = np.array([1, 2, 3, 2, 1, 6])
  4. # create sliding window
  5. v = swv(np.pad(a.astype(float), (k-1, 0), constant_values=np.nan), k)
  6. # compare each element to min/max of sliding window
  7. out = np.select([np.max(v, 1)==a, np.min(v, 1)==a], [1, -1], 0)

Output: array([ 0, 0, 1, -1, -1, 1])

huangapple
  • 本文由 发表于 2023年2月8日 16:04:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75382825.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定