首页 > 解决方案 > 对数据框中的下 i 行使用 Python 循环

问题描述

我是一个新的 Python 用户(从 VBA 转变)并且在弄清楚 Python 的循环函数时遇到了麻烦。我有一个数据框 df,我想根据循环在另一列中满足某些条件来创建一列变量。如下所示:

cycle = 5
dummy = 1

for i = 1 to cycle
    if df["high"].iloc[i] >= df["exit"].iloc[i] and
    df["low"].iloc[i] <= df["exit"].iloc[i] then
        df["signal"] = dummy
        break
    elif i = cycle
        df["signal"] = cycle + 1
        break
    else:
        dummy = dummy + 1
        next i

基本上试图找出循环变量之前的下一列中的哪一列是if语句中的条件满足,如果它们从未满足,则分配循环+ 1。所以df["signal"]将是一列范围为1->(周期 + 1)。此外, 中有一些 NaN 值df["exit"],不确定它如何影响循环。

我在网站上找到了关于行迭代的相当广泛的文档,我觉得这接近我需要到达的地方,但不知道如何调整它。感谢您的任何建议!

编辑:包含以下 EXCEL 单元格的数据样本:

high low EXIT test   signal/(OUTPUT COLUMN)
4     3    4    1      1
2     2    2    1      1
2     3    5    0      6
4     3    1    0      5
2     5    2    0      4
5     5    1    0      3
3     1    5    0      2
5     1    5    1      1
1     1    4    0      0

编辑2:围绕脚本的进一步澄清 一旦条件

df["high"].iloc[i] >= df["exit"].iloc[i] and
    df["low"].iloc[i] <= df["exit"].iloc[i]

在循环中遇到,它应该为那个特定的实例/行终止。

编辑 3:预期输出

预期的输出是 df["signal"] 列 - 它是循环中条件的第一个实例

 df["high"].iloc[i] >= df["exit"].iloc[i] and
    df["low"].iloc[i] <= df["exit"].iloc[i]

在任何给定的行中都满足。df["signal"] 中的输出实际上i来自循环或给定的迭代。

标签: pythonexcelpandasdataframe

解决方案


这是我解决问题的方法,'gr'在执行此操作之前该列必须不存在:

# first check all the rows meeting the conditions and add 1 in a temporary column gr
df.loc[(df["high"] >= df["exit"]) & (df["low"] <= df["exit"]), 'gr'] = 1
# manipulate column gr to use groupby after
df['gr'] = df['gr'].cumsum().bfill()
# use cumcount after groupby to recalculate signal
df.loc[:,'signal'] = df.groupby('gr').cumcount(ascending=False).add(1)
# cut the value in signal to the value cycle + 1
df.loc[df['signal'] > cycle, 'signal'] = cycle + 1
# drop column gr
df = df.drop('gr',1)

你得到

   high  low  exit  signal
0     4    3     4       1
1     2    2     2       1
2     2    3     5       6
3     4    3     1       5
4     2    5     2       4
5     5    5     1       3
6     3    1     5       2
7     5    1     5       1
8     1    1     4       1

注意:最后一行无法正常工作,因为之后再也没有满足条件的行,并且不确定它在完整数据中的情况或如何处理。您可以考虑df = df.dropna(subset=['gr'])在开头的行之后添加df['gr'] = ...以删除最后几行,这取决于您。


推荐阅读