簡體   English   中英

條件檢查基於 Pandas 滾動 window

[英]Condition check based on Pandas rolling window

根據下面的可重現代碼,我有以下 dataframe:

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 個周期的滾動 window
  • 如果在過去 20 個期間有行 df['20MA'] > df['200MA'] &
  • 如果在最后 20 個期間也有行是 df['20MA'] < df['200MA']

所需的 output:

  • 如果滿足條件,則將值“中性”添加到名為“趨勢 20 窗口”的新列中。

我曾嘗試在 Pandas 中使用滾動 window 功能,但難以獲得所需的結果。

重現示例的代碼:

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"

您可以使用通過使用.gt().lt()df['20MA']df['200MA']進行比較而創建的 boolean 掩碼,並通過檢查.sum() ) 來檢查使用.rolling()滾動 window 的結果在滾動 windows 中滿足條件的行數 >=1 且.ge(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 行)用較小的滾動 window 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                

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM