Python 基于滚动窗口的状态检测
根据下面的可复制代码,我有以下数据帧:Python 基于滚动窗口的状态检测,python,pandas,Python,Pandas,根据下面的可复制代码,我有以下数据帧: df.tail(10) open high low close 200MA 20MA Trend date 2020-12-24 1.3273 1.3384 1.3257 1.3384 1.324826 1.325365 Up 2020-12-25 1.3408 1.3408 1.3268 1.326
df.tail(10)
open high low close 200MA 20MA Trend
date
2020-12-24 1.3273 1.3384 1.3257 1.3384 1.324826 1.325365 Up
2020-12-25 1.3408 1.3408 1.3268 1.3268 1.324926 1.326240 Up
2020-12-26 1.3268 1.3283 1.3217 1.3239 1.325008 1.326085 Up
2020-12-27 1.3240 1.3240 1.3078 1.3078 1.325009 1.325215 Up
2020-12-28 1.3103 1.3103 1.2878 1.2878 1.324973 1.323490 Down
2020-12-29 1.2893 1.2932 1.2876 1.2886 1.324951 1.321890 Down
2020-12-30 1.2871 1.2937 1.2810 1.2906 1.324923 1.319755 Down
2020-12-31 1.2905 1.3020 1.2905 1.2993 1.324934 1.318450 Down
2021-01-01 1.3006 1.3022 1.2896 1.2905 1.324893 1.316830 Down
2021-01-02 1.2909 1.3085 1.2890 1.3008 1.324908 1.315660 Down
我需要一个基于以下条件的新列:
- 每行回顾20个周期的滚动窗口
- 如果在过去20个周期内,有df['20MA']>df['200MA']的行&
- 如果在过去20个周期内,也有行为df['20MA']
import pandas as pd
import numpy as np
def genMockDataFrame(days,startPrice,colName,startDate,seed=None):
periods = days*24
np.random.seed(seed)
steps = np.random.normal(loc=0, scale=0.0018, size=periods)
steps[0]=0
P = startPrice+np.cumsum(steps)
P = [round(i,4) for i in P]
fxDF = pd.DataFrame({
'ticker':np.repeat( [colName], periods ),
'date':np.tile( pd.date_range(startDate, periods=periods, freq='H'), 1 ),
'price':(P)})
fxDF.index = pd.to_datetime(fxDF.date)
fxDF = fxDF.price.resample('D').ohlc()
return fxDF
df = genMockDataFrame(290,1.1904,'eurusd','19/3/2020',seed=1)
df["200MA"] = df["close"].rolling(window=200).mean()
df["20MA"] = df["close"].rolling(window=20).mean()
df.loc[df['20MA'] > df['200MA'], "Trend"] = "Up"
df.loc[df['20MA'] < df['200MA'], "Trend"] = "Down"
- 如果满足条件,将值“中性”添加到名为“趋势20窗口”的新列中
import pandas as pd
import numpy as np
def genMockDataFrame(days,startPrice,colName,startDate,seed=None):
periods = days*24
np.random.seed(seed)
steps = np.random.normal(loc=0, scale=0.0018, size=periods)
steps[0]=0
P = startPrice+np.cumsum(steps)
P = [round(i,4) for i in P]
fxDF = pd.DataFrame({
'ticker':np.repeat( [colName], periods ),
'date':np.tile( pd.date_range(startDate, periods=periods, freq='H'), 1 ),
'price':(P)})
fxDF.index = pd.to_datetime(fxDF.date)
fxDF = fxDF.price.resample('D').ohlc()
return fxDF
df = genMockDataFrame(290,1.1904,'eurusd','19/3/2020',seed=1)
df["200MA"] = df["close"].rolling(window=200).mean()
df["20MA"] = df["close"].rolling(window=20).mean()
df.loc[df['20MA'] > df['200MA'], "Trend"] = "Up"
df.loc[df['20MA'] < df['200MA'], "Trend"] = "Down"
将熊猫作为pd导入
将numpy作为np导入
def genMockDataFrame(天、startPrice、colName、startDate、seed=None):
周期=天*24
np.随机种子(种子)
步数=np.随机.正常(loc=0,刻度=0.0018,大小=周期)
步数[0]=0
P=startPrice+np.cumsum(步数)
P=[P中i的第(i,4)轮]
fxDF=pd.DataFrame({
“ticker”:名词重复([colName],句点),
“日期”:np.tile(pd.date_范围(起始日期,周期=周期,频率=H'),1),
‘价格’:(P)})
fxDF.index=pd.to_datetime(fxDF.date)
fxDF=fxDF.price.resample('D').ohlc()
返回fxDF
df=genMockDataFrame(290,1.1904,'EURUUSD','19/3/2020',seed=1)
df[“200MA”]=df[“关闭”]。滚动(窗口=200)。平均值()
df[“20MA”]=df[“关闭”]。滚动(窗口=20)。平均值()
df.loc[df['20MA']>df['200MA'],“趋势”]=“上升”
df.loc[df['20MA']
您可以使用通过使用.gt()
和.lt()
将df['20MA']
与df['200MA']
进行比较而创建的布尔掩码,并通过检查.sum()
在.ge>滚动窗口中满足条件的行数>=1来检查滚动窗口中的结果(1)
。然后在掩码上使用.loc()
为匹配行的新列指定“中性”,如下所示:
df['Trend 20 Window'] = '' # init to ''
periods = 20
mask = df['20MA'].gt(df['200MA']).rolling(periods).sum().ge(1) & df['20MA'].lt(df['200MA']).rolling(periods).sum().ge(1)
df.loc[mask, 'Trend 20 Window'] = 'Neutral'
演示
让我们用您的样本数据(10行)进行测试,使用较小的滚动窗口3:
df['Trend 20 Window'] = ''
periods = 3
mask = df['20MA'].gt(df['200MA']).rolling(periods).sum().ge(1) & df['20MA'].lt(df['200MA']).rolling(periods).sum().ge(1)
df.loc[mask, 'Trend 20 Window'] = 'Neutral'
结果:
open high low close 200MA 20MA Trend Trend 20 Window
date
2020-12-24 1.3273 1.3384 1.3257 1.3384 1.324826 1.325365 Up
2020-12-25 1.3408 1.3408 1.3268 1.3268 1.324926 1.326240 Up
2020-12-26 1.3268 1.3283 1.3217 1.3239 1.325008 1.326085 Up
2020-12-27 1.3240 1.3240 1.3078 1.3078 1.325009 1.325215 Up
2020-12-28 1.3103 1.3103 1.2878 1.2878 1.324973 1.323490 Down Neutral
2020-12-29 1.2893 1.2932 1.2876 1.2886 1.324951 1.321890 Down Neutral
2020-12-30 1.2871 1.2937 1.2810 1.2906 1.324923 1.319755 Down
2020-12-31 1.2905 1.3020 1.2905 1.2993 1.324934 1.318450 Down
2021-01-01 1.3006 1.3022 1.2896 1.2905 1.324893 1.316830 Down
2021-01-02 1.2909 1.3085 1.2890 1.3008 1.324908 1.315660 Down
您可以使用通过使用
.gt()
和.lt()
将df['20MA']
与df['200MA']
进行比较而创建的布尔掩码,并通过使用检查满足滚动窗口内条件的行数的.sum()
检查滚动窗口内的结果
。然后在掩码上使用.loc()
为匹配行的新列指定“中性”,如下所示:
df['Trend 20 Window'] = '' # init to ''
periods = 20
mask = df['20MA'].gt(df['200MA']).rolling(periods).sum().ge(1) & df['20MA'].lt(df['200MA']).rolling(periods).sum().ge(1)
df.loc[mask, 'Trend 20 Window'] = 'Neutral'
演示
让我们用您的样本数据(10行)进行测试,使用较小的滚动窗口3:
df['Trend 20 Window'] = ''
periods = 3
mask = df['20MA'].gt(df['200MA']).rolling(periods).sum().ge(1) & df['20MA'].lt(df['200MA']).rolling(periods).sum().ge(1)
df.loc[mask, 'Trend 20 Window'] = 'Neutral'
结果:
open high low close 200MA 20MA Trend Trend 20 Window
date
2020-12-24 1.3273 1.3384 1.3257 1.3384 1.324826 1.325365 Up
2020-12-25 1.3408 1.3408 1.3268 1.3268 1.324926 1.326240 Up
2020-12-26 1.3268 1.3283 1.3217 1.3239 1.325008 1.326085 Up
2020-12-27 1.3240 1.3240 1.3078 1.3078 1.325009 1.325215 Up
2020-12-28 1.3103 1.3103 1.2878 1.2878 1.324973 1.323490 Down Neutral
2020-12-29 1.2893 1.2932 1.2876 1.2886 1.324951 1.321890 Down Neutral
2020-12-30 1.2871 1.2937 1.2810 1.2906 1.324923 1.319755 Down
2020-12-31 1.2905 1.3020 1.2905 1.2993 1.324934 1.318450 Down
2021-01-01 1.3006 1.3022 1.2896 1.2905 1.324893 1.316830 Down
2021-01-02 1.2909 1.3085 1.2890 1.3008 1.324908 1.315660 Down