在dataframe中,如何使用布尔输出检测两个不同列(行)的交叉?

2024-09-27 00:21:41 发布

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

我仍在学习python,并尝试实时扫描最新股价,在我的工作流程中,我有两个不同的数据帧

(1)数据帧实时运行,以根据最新的开盘价/高/低/收盘价(OHLC)以及LineA和LineB检测某些情况。后几行基于OHLC值。它们以相同的名称显示在6列中。索引就是时间。在本例中,每行表示1分钟,每过一分钟,数据帧中就会出现新行。此处用于基于最新行检查交叉的代码具有以下类型的书写样式:

def check_crossover(df):

    cond1 = any([(candles.lineA[-1] < candles.lineB[-1] and candles.lineA[-2] > candles.lineB[-2]),(candles.lineA[-2] < candles.lineB[-2] and candles.lineA[-3] > candles.lineB[-3])])

    return any([cond1,cond2])

我试图检测LineB是否从上方下降到LineA下方。让我们假设现在是0900,我试图检测这些交叉是否发生在0858到0859之间,或者0859到0900之间

转换为数据帧中的行,我尝试使用上面的代码查找当前行和前两行中的交叉

我试过用python运行,它给了我一个错误的响应,所以我认为它是正确的

可以建议这是否正确,或者是否有更好的方法来写这篇文章?

(2)相同的确切数据帧,但这次我尝试填充表示上述cond1结果的额外列,每行。因此,如果一行在当前行和前两行中未显示任何交叉,则“Cond1”列下的当前行将为“False”

这里的目的是让我检查实时脚本是否正确运行

def cond1(df):
    df.loc[:, ('cond1a')] = df.LineA < df.LineB and df.LineA.shift(1) > df.LineB.shift(1)
    df.loc[:, ('cond1b')] = (df.LineA.shift(1) < df.LineB.shift(1) and df.LineA.shift(2) > df.LineB.shift(2))
    df.loc[:, ('cond1')] = df[['cond1a', 'cond1b']].all(axis=1)

    return df

这给了我一个错误‘序列的真值是模糊的’。使用a.empty、a.bool()、a.item()、a.any()或a.all()。“我刚刚了解到Python和Pandas使用.any()和.all()有自己的方式,但我在这里迷路了

如果我需要两个条件都为真,或者只需要其中一个条件为真,我应该如何写这篇文章?

请告知


Tags: and数据dfshiftanyall交叉loc
1条回答
网友
1楼 · 发布于 2024-09-27 00:21:41

问题是and的使用。对于要使用&的类数组对象的布尔比较(请参见此question)。此外,您需要确保使用括号将逻辑&与带有<>的测试分开。最后,函数cond1就地更新数据帧df,因此不需要在函数末尾使用return

总之:

 def cond1(df):
     df.loc[:, ('cond1a')] = (df.LineA < df.LineB) & (df.LineA.shift(1) > df.LineB.shift(1))
     df.loc[:, ('cond1b')] = (df.LineA.shift(1) < df.LineB.shift(1)) & (df.LineA.shift(2) > df.LineB.shift(2))
     df.loc[:, ('cond1')] = df[['cond1a', 'cond1b']].all(axis=1)

编辑:关于您的第一个问题,首先比较lineAlineB以获得布尔索引,然后检查该索引何时从True翻转到False可能更容易。这将为您提供迄今为止的所有交叉点:

cond = df.lineA < df.lineB  # checks for all times whether lineB is above lineA
cond != cond.shift(1)  # returns True for all times, where lineB dips below lineA

相关问题 更多 >

    热门问题