如何在Python中创建一个简单的标志

2024-05-21 06:35:31 发布

您现在位置:Python中文网/ 问答频道 /正文

从雅虎获得间谍数据后,我创建了一个收盘价的渠道,如下所示,最大和最小滚动窗口。色谱柱为HC和HL。在

我需要创建一个列(我称之为flag),当收盘价等于HC时显示1,并且这个值一直持续到close将等于HL。此时Flag的值将为-1。如您所见,它非常简单,标志只能有两个值:1或-1。在

简单的公式如下:

  1. 如果Close==HC,则标志为1
  2. 如果Close==HL,则标志为-1
  3. 如果接近!=HC并关闭!=HL则标志等于变量标志上保存的最后一个值。在

我试过几次,包括下面的代码。此代码的问题是显示了0值。我不知道如何通过一个条件使它消失:

import pandas as pd
import pandas_datareader as dr
import numpy as np
from datetime import date

df = dr.data.get_data_yahoo('SPY',start='01-01-2019',end=date.today())

df['HC'] = df['Close'].rolling(20).max() 
df['LC'] = df['Close'].rolling(20).min() 

df['Flag'] = [1 if (df.loc[ei, 'Close'] == df.loc[ei, 'HC']) else 
              -1 if (df.loc[ei, 'Close'] == df.loc[ei, 'LC']) else   
              0 for ei in df.index]

下面你可以看到蓝色的结果我的代码和红色的结果,我需要的结果。在

Image

有简单的方法吗?如果有人能帮我,我会很感激的。谢谢您!在


Tags: 代码hcimportpandasdfclosedate标志
3条回答

一个简单的方法是使用一个循环,但从时间上讲,这是低效的。但是,如果您不介意的话,可以在数组中循环

flag01 = 0
for ei in df.index:
    if (df.loc[ei, 'Close'] == df.loc[ei, 'HC']):
        flag01 = 1
    if (df.loc[ei, 'Close'] == df.loc[ei, 'LC'])
        flag01 = -1
    df.loc[ei, 'Flag'] = flag01

基本上你设置了0,每当你发现条件为真时,你就设置为1并保持1直到条件满足变成-1,依此类推。这比您使用的方法要慢,但这是“保留最后一个值”的最简单方法,因为您正在增加值,并且您知道之前的值。在

尽管已经回答了这个问题,但是计算这种结果的最快方法通常是使用np.where,如下所示:

import pandas as pd
import pandas_datareader as dr
import numpy as np
from datetime import date

df = dr.data.get_data_yahoo('SPY',start='01-01-2019',end=date.today())

df['HC'] = df['Close'].rolling(20).max() 
df['LC'] = df['Close'].rolling(20).min() 

以下是嵌套逻辑:

  1. 创建空数组
  2. 在条件下,将值替换为-1
  3. 条件下将值替换为1
^{pr2}$

在性能方面:

%%timeit
df['Flag'] = np.where((df.Close == df.HC), 1, 
         np.where(df.Close == df.LC, -1, np.full(df.Close.count(), np.nan)))
df.Flag.fillna(method='ffill', inplace=True)
912 µs ± 49.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

这绝对比循环或嵌套if条件更好。在

例如@Tim Mironov回答:

%%timeit
pos_indexes = (df.Close == df.HC)
neg_indexes = (df.Close == df.LC)

df.loc[pos_indexes, 'Good_Flag'] = 1
df.loc[neg_indexes, 'Good_Flag'] = -1

df.fillna(method='ffill', inplace=True)
4.43 ms ± 92 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

您可以使用Pandas的更多内置功能,特别是fillna方法和逻辑索引的使用。 我在原始代码中添加了一部分代码,以创建一个附加的Good_Flag

import pandas_datareader as dr
from datetime import date

df = dr.data.get_data_yahoo('SPY',start='01-01-2019',end=date.today())

df['HC'] = df['Close'].rolling(20).max() 
df['LC'] = df['Close'].rolling(20).min() 

df['Flag'] = [1 if (df.loc[ei, 'Close'] == df.loc[ei, 'HC']) else 
              -1 if (df.loc[ei, 'Close'] == df.loc[ei, 'LC']) else   
              0 for ei in df.index]

pos_indexes = df.Close == df.HC
neg_indexes = df.Close == df.LC
df.loc[pos_indexes, 'Good_Flag'] = 1
df.loc[neg_indexes, 'Good_Flag'] = -1
df = df.fillna(method='ffill')

请注意,我使用了带有ffill属性的fillna方法来指定“前向传递”。在

编辑: 为了澄清这一点,原始的Flag列故意留在这里,新的Good_Flag列的计算不依赖Flag。在

为了展示理想的行为:

^{pr2}$

enter image description here

相关问题 更多 >