【问题标题】:IF statement / For Loop dilemma for formulaIF 语句 / For Loop 公式的困境
【发布时间】:2021-07-31 17:42:04
【问题描述】:

所以我已经被这个问题困扰了一段时间了。我正在尝试在 Python 中复制以下公式:

 FINAL UPPERBAND = IF( (Current BASICUPPERBAND < Previous FINAL
 UPPERBAND) or (Previous Close > Previous FINAL UPPERBAND))
                     THEN (Current BASIC UPPERBAND) ELSE Previous FINALUPPERBAND)

我的问题是让我失望的是如何在 If 语句中使用它时创建 FINAL UPPERBAND。作为参考,BASIC UPPERBAND 和 CLOSES 是它们自己的数据帧,这也让它变得有点棘手。我能想到的唯一方法是 for 循环,但数据帧非常大,所以需要很长时间。

我尝试过其他东西,例如 pandas.where apply 和类似 final_uppers[(basic_uppers &lt; basic_uppers.shift(1))] = basic_uppers 的东西,当我将它们加在一起时,大部分是正确的答案,但大约 1/4 是错误的。我相信这是由于不按顺序填充行。这就是我现在所拥有的,但就像我说的仍然存在不正确的值:

final_uppers = pd.DataFrame(columns=closes.columns, index=closes.index)
final_uppers = final_uppers.fillna(0)
final_uppers[(basic_uppers < basic_uppers.shift(1))] = basic_uppers
final_uppers[(closes.shift(1) > final_uppers.shift(1))] = basic_uppers
final_uppers = final_uppers.replace(to_replace=0, method='ffill')

编辑:可以使用 Lambda 函数和 .apply 吗?尝试过,但只是得到 DataFrame 是模棱两可的。

任何帮助将不胜感激,或者如果有人可以帮助我进行循环只是为了测试使用循环需要多长时间。但是任何关于如何解决这个问题的想法都将不胜感激。 :)

也许这样的事情可能会起作用:

final_uppers = pd.DataFrame(columns=closes.columns, index=closes.index)
final_uppers = final_uppers.fillna(0)

for i in range(1, len(final_uppers)):
    if (basic_uppers.iloc[i] < final_uppers[i-1]) | (closes.iloc[i-1] > final_uppers[i-1]):
        final_uppers.append(basic_uppers.iloc[i])
    else:
        final_uppers.append(final_uppers[i-1])
final_uppers = final_uppers

【问题讨论】:

    标签: python pandas dataframe for-loop if-statement


    【解决方案1】:

    假设您的数据可以作为字典列表给出,那么我想您想要的是以下内容?

    lst = [{'basic_upperband': 5, 'close': 23, 'final_upperband': 0},
           {'basic_upperband': -2, 'close': 20},
           {'basic_upperband': 2, 'close': 19},
           {'basic_upperband': 1, 'close': 25}]
    
    for i in range(1, len(lst)):
        if lst[i]['basic_upperband'] < lst[i-1]['final_upperband'] or lst[i-1]['close'] < lst[i-1]['final_upperband']:
            lst[i]['final_upperband'] = lst[i]['basic_upperband']
        else:
            lst[i]['final_upperband'] = lst[i-1]['final_upperband']
    
    print(lst)
    

    如果您的数据已经是一个数据框,您可以遍历行并使用类似以下内容构建 final_upperband 列

    import pandas as pd
    df = pd.DataFrame([{'basic_upperband': 5, 'close': 23},
                       {'basic_upperband': -2, 'close': 20},
                       {'basic_upperband': 2, 'close': 19},
                       {'basic_upperband': 1, 'close': 25}])
    
    final_upperband = [0]
    for i in range(1, len(df)):
        if df.iloc[i]['basic_upperband'] < final_upperband[i-1] or df.iloc[i-1]['close'] < final_upperband[i-1]:
            final_upperband.append(df.iloc[i]['basic_upperband'])
        else:
            final_upperband.append(final_upperband[i-1])
    df['final_upperband'] = final_upperband
    

    【讨论】:

    • 嗨,是的,我的数据目前已经在单独的数据帧中,所以目前所有基本的上带值都在 df 中,所有关闭都在 df 中,然后我想创建最终的上带作为它自己的 df .能给个简单的iterrows例子吗,没用过,不胜感激
    • 使用 iterrows 并没有我想象的那么容易,所以另一种方法是构建列然后添加它
    • 仍然不确定它是否适合我的情况。我有一个包含所有收盘价的 DataFrame,以及一个用于 Basic Upperband 的单独 DataFrame,我想为 Final Upperbands 创建一个新的 DataFrame。如您的示例所示,我的数据不在列名下的一个数据框中,因此在您比较列基本上带的 if 语句中,我需要一些东西来检查包含所有关闭的实际数据框
    • 好吧,您可以只合并两个数据框 - 或者如果它们始终包含相同数量的行,您可以简单地更改引用的名称,以使用您关闭的数据框的名称。
    • 是的,它们的行数总是相同的。合并可能很困难,因为我有 500 列。我将如何更改名称并且仍然能够逐行进行,在问题中添加了一个示例,尚未对其进行测试
    猜你喜欢
    • 1970-01-01
    • 2013-09-02
    • 2018-04-16
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多