在 Pandas 中找到移动平均线的当前交叉点和先前交叉点之间的最小值
Find the minimum value between a current and previous crossovers of moving-averages in Pandas
我有一个很大的股票价格数据框 df.columns = ['open','high','low','close']
问题定义:
当发生 EMA 交叉时,我指的是 df['cross'] = cross。每次发生交叉时,如果我们将当前交叉标记为交叉 4,我想检查交叉 3 和 4 之间的 df['low'] 的最小值是否大于 df['low' 的最小值] 在交叉点 1 和交叉点 2 之间。到目前为止,我已经根据从 'Gherka' 收到的帮助尝试编写代码。我已经对交叉进行了索引,并找到了连续交叉之间的最小值。
因此,每次发生交叉时,都必须将其与前 3 次交叉进行比较,我需要检查 MIN(CROSS4,CROSS 3) > MIN(CROSS2,CROSS1)。
如果你们能帮助我完成,我将不胜感激。
import pandas as pd
import numpy as np
import bisect as bs
data = pd.read_csv("Nifty.csv")
df = pd.DataFrame(data)
df['5EMA'] = df['Close'].ewm(span=5).mean()
df['10EMA'] = df['Close'].ewm(span=10).mean()
condition1 = df['5EMA'].shift(1) < df['10EMA'].shift(1)
condition2 = df['5EMA'] > df['10EMA']
df['cross'] = np.where(condition1 & condition2, 'cross', None)
cross_index_array = df.loc[df['cross'] == 'cross'].index
def find_index(a, x):
i = bs.bisect_left(a, x)
return a[i-1]
def min_value(x):
"""Find the minimum value of 'Low' between crossovers 1 and 2, crossovers 3 and 4, etc..."""
cur_index = x.name
prev_cross_index = find_index(cross_index_array, cur_index)
return df.loc[prev_cross_index:cur_index, 'Low'].min()
df['min'] = None
df['min'][df['cross'] == 'cross'] = df.apply(min_value, axis=1)
print(df)
这应该可以解决问题:
import pandas as pd
df = pd.DataFrame({'open': [1, 2, 3, 4, 5],
'high': [5, 6, 6, 5, 7],
'low': [1, 3, 3, 4, 4],
'close': [3, 5, 3, 5, 6]})
df['day'] = df.apply(lambda x: 'bull' if (
x['close'] > x['open']) else None, axis=1)
df['min'] = None
df['min'][df['day'] == 'bull'] = pd.rolling_min(
df['low'][df['day'] == 'bull'], window=2)
print(df)
# close high low open day min
# 0 3 5 1 1 bull NaN
# 1 5 6 3 2 bull 1
# 2 3 6 3 3 None None
# 3 5 5 4 4 bull 3
# 4 6 7 4 5 bull 4
公开征求意见!
如果我对你的问题的理解正确,你需要一个动态的 "rolling window" 来计算最小值。假设您的索引是默认索引,这意味着它按升序排序,您可以尝试以下方法:
import pandas as pd
import numpy as np
from bisect import bisect_left
df = pd.DataFrame({'open': [1, 2, 3, 4, 5],
'high': [5, 6, 6, 5, 7],
'low': [1, 3, 2, 4, 4],
'close': [3, 5, 3, 5, 6]})
这使用与 mommermi 相同的样本数据,但将第三天的低点更改为 2,因为第三天也应包含在 "rolling window" 中。
df['day'] = np.where(df['close'] > df['open'], 'bull', None)
我们使用矢量化 numpy 运算计算 day
列,这应该会更快一些。
bull_index_array = df.loc[df['day'] == 'bull'].index
我们存储我们标记为多头的行(天)的索引值。
def find_index(a, x):
i = bisect_left(a, x)
return a[i-1]
核心库中的Bisect将使我们能够以高效的方式找到前一个牛市的指数。这要求索引按默认排序。
def min_value(x):
cur_index = x.name
prev_bull_index = find_index(bull_index_array, cur_index)
return df.loc[prev_bull_index:cur_index, 'low'].min()
接下来,我们定义一个函数,它将通过按先前和当前索引对原始数据帧进行切片来创建 "dynamic" 滚动 window。
df['min'] = df.apply(min_value, axis=1)
最后,我们将 min_value 函数逐行应用于数据框,得到:
open high low close day min
0 1 5 1 3 bull NaN
1 2 6 3 5 bull 1.0
2 3 6 2 3 None 2.0
3 4 5 4 5 bull 2.0
4 5 7 4 6 bull 4.0
我有一个很大的股票价格数据框 df.columns = ['open','high','low','close']
问题定义: 当发生 EMA 交叉时,我指的是 df['cross'] = cross。每次发生交叉时,如果我们将当前交叉标记为交叉 4,我想检查交叉 3 和 4 之间的 df['low'] 的最小值是否大于 df['low' 的最小值] 在交叉点 1 和交叉点 2 之间。到目前为止,我已经根据从 'Gherka' 收到的帮助尝试编写代码。我已经对交叉进行了索引,并找到了连续交叉之间的最小值。 因此,每次发生交叉时,都必须将其与前 3 次交叉进行比较,我需要检查 MIN(CROSS4,CROSS 3) > MIN(CROSS2,CROSS1)。
如果你们能帮助我完成,我将不胜感激。
import pandas as pd
import numpy as np
import bisect as bs
data = pd.read_csv("Nifty.csv")
df = pd.DataFrame(data)
df['5EMA'] = df['Close'].ewm(span=5).mean()
df['10EMA'] = df['Close'].ewm(span=10).mean()
condition1 = df['5EMA'].shift(1) < df['10EMA'].shift(1)
condition2 = df['5EMA'] > df['10EMA']
df['cross'] = np.where(condition1 & condition2, 'cross', None)
cross_index_array = df.loc[df['cross'] == 'cross'].index
def find_index(a, x):
i = bs.bisect_left(a, x)
return a[i-1]
def min_value(x):
"""Find the minimum value of 'Low' between crossovers 1 and 2, crossovers 3 and 4, etc..."""
cur_index = x.name
prev_cross_index = find_index(cross_index_array, cur_index)
return df.loc[prev_cross_index:cur_index, 'Low'].min()
df['min'] = None
df['min'][df['cross'] == 'cross'] = df.apply(min_value, axis=1)
print(df)
这应该可以解决问题:
import pandas as pd
df = pd.DataFrame({'open': [1, 2, 3, 4, 5],
'high': [5, 6, 6, 5, 7],
'low': [1, 3, 3, 4, 4],
'close': [3, 5, 3, 5, 6]})
df['day'] = df.apply(lambda x: 'bull' if (
x['close'] > x['open']) else None, axis=1)
df['min'] = None
df['min'][df['day'] == 'bull'] = pd.rolling_min(
df['low'][df['day'] == 'bull'], window=2)
print(df)
# close high low open day min
# 0 3 5 1 1 bull NaN
# 1 5 6 3 2 bull 1
# 2 3 6 3 3 None None
# 3 5 5 4 4 bull 3
# 4 6 7 4 5 bull 4
公开征求意见!
如果我对你的问题的理解正确,你需要一个动态的 "rolling window" 来计算最小值。假设您的索引是默认索引,这意味着它按升序排序,您可以尝试以下方法:
import pandas as pd
import numpy as np
from bisect import bisect_left
df = pd.DataFrame({'open': [1, 2, 3, 4, 5],
'high': [5, 6, 6, 5, 7],
'low': [1, 3, 2, 4, 4],
'close': [3, 5, 3, 5, 6]})
这使用与 mommermi 相同的样本数据,但将第三天的低点更改为 2,因为第三天也应包含在 "rolling window" 中。
df['day'] = np.where(df['close'] > df['open'], 'bull', None)
我们使用矢量化 numpy 运算计算 day
列,这应该会更快一些。
bull_index_array = df.loc[df['day'] == 'bull'].index
我们存储我们标记为多头的行(天)的索引值。
def find_index(a, x):
i = bisect_left(a, x)
return a[i-1]
核心库中的Bisect将使我们能够以高效的方式找到前一个牛市的指数。这要求索引按默认排序。
def min_value(x):
cur_index = x.name
prev_bull_index = find_index(bull_index_array, cur_index)
return df.loc[prev_bull_index:cur_index, 'low'].min()
接下来,我们定义一个函数,它将通过按先前和当前索引对原始数据帧进行切片来创建 "dynamic" 滚动 window。
df['min'] = df.apply(min_value, axis=1)
最后,我们将 min_value 函数逐行应用于数据框,得到:
open high low close day min
0 1 5 1 3 bull NaN
1 2 6 3 5 bull 1.0
2 3 6 2 3 None 2.0
3 4 5 4 5 bull 2.0
4 5 7 4 6 bull 4.0