You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas DataFrame条件匹配与新列生成报错问题求助

问题解决:Pandas中检查后续行满足条件并新增列

原始DataFrame

High     Close    
Close Time                                                                                                                    
2022-10-23 21:41:59.999  19466.02  19461.29       
2022-10-23 21:42:59.999  19462.48  19457.83         
2022-10-23 21:43:59.999  19463.13  19460.09         
2022-10-23 21:44:59.999  19465.15  19463.76

需求说明

  • 对每一行,检查其之后最多600行内是否存在某一行同时满足:
    1. 该行的Close值 > 当前行的Close值
    2. 该行的High值 < 当前行的High值
  • 满足条件时,新增LC、HC、HH、LH列记录对应值:
    • LC:当前行的Close值(仅当前行填充)
    • HC:目标行的Close值(仅目标行填充)
    • HH:当前行的High值(仅当前行填充)
    • LH:目标行的High值(仅目标行填充)

预期输出

High     Close         LC        HC         HH        LH
Close Time                                                                                                                    
2022-10-23 21:41:59.999  19466.02  19461.29   19461.29       NaN   19466.02       NaN
2022-10-23 21:42:59.999  19462.48  19457.83        NaN       NaN        NaN       NaN
2022-10-23 21:43:59.999  19463.13  19460.09        NaN       NaN        NaN       NaN
2022-10-23 21:44:59.999  19465.15  19463.76        NaN  19463.76        NaN  19465.15

尝试的代码及报错

第一次尝试代码

# Checking if conditions are met

for i in range(len(df)):
    for a in range(i,600):
        if (df.iloc[i:, 1] < df.iloc[a, 1]) & (df.iloc[i:, 0] > df.iloc[a, 0]):

            # Creating new DataFrame columns

            df['LC'] = df.iloc[i, 1]
            df['HC'] = df.get_loc[i,1]
            df['HH'] = df.get_loc[a, 0]
            df['LH'] = df.get_loc[a, 0]

        else:
            continue

报错信息

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

问题分析

  • df.iloc[i:, 1]返回的是从第i行开始的Series,和单个值df.iloc[a,1]比较后得到布尔Series,直接放在if条件里会触发歧义报错——Pandas无法判断你要的是"全满足"还是"任一满足"。
  • df.get_loc()是用来获取列名对应的索引位置的,不能用来取单元格值,这里用法完全错误,应该用df.iloc直接取值。

第二次尝试代码

idx_close, idx_high = map(df.columns.get_loc, ["Close", "High"])

# Check Conditions
for i in range(len(df)):
    bool_l = [((df.iloc[i, idx_close] < df.iloc[a, idx_close]) &
                (df.iloc[i, idx_high] > df.iloc[a, idx_high])
                 ).any() for a in range(i, 600)]

    # Creating new DataFrame columns
    df.loc[i, 'LC'] = df.iloc[i,1]
    df.loc[bool_l, 'HC'] = df.iloc[bool_l, 1]

    # Creating new DataFrame columns
    df.loc[i, 'HH'] = df.iloc[i, 0]
    df.loc[bool_l, 'LH'] = df.iloc[bool_l, 0]

报错信息

IndexError: Boolean index has wrong length: 600 instead of 2867

问题分析

  • bool_l是长度为600的布尔列表,但你的DataFrame有2867行,用短列表去索引长DataFrame的行,必然长度不匹配报错。
  • range(i,600)写法错误:当i大于600时这个范围是空的,而且应该取i+1到min(i+600, len(df)),确保只检查当前行之后的最多600行,且不超出DataFrame范围。

解决方案

下面是修正后的代码,解决了上述所有问题:

import pandas as pd

# 先初始化新增的4列为缺失值
df[['LC', 'HC', 'HH', 'LH']] = pd.NA

# 获取列对应的索引位置
idx_close = df.columns.get_loc('Close')
idx_high = df.columns.get_loc('High')
idx_lc = df.columns.get_loc('LC')
idx_hc = df.columns.get_loc('HC')
idx_hh = df.columns.get_loc('HH')
idx_lh = df.columns.get_loc('LH')

total_rows = len(df)

for i in range(total_rows):
    # 确定后续检查的结束索引:最多查当前行之后600行,不超过总行数
    end_idx = min(i + 601, total_rows)
    # 遍历当前行之后的行(从i+1开始)
    for a in range(i+1, end_idx):
        # 单个行的条件判断,不会产生布尔Series
        if (df.iloc[a, idx_close] > df.iloc[i, idx_close]) and (df.iloc[a, idx_high] < df.iloc[i, idx_high]):
            # 填充当前行的LC和HH
            df.iloc[i, idx_lc] = df.iloc[i, idx_close]
            df.iloc[i, idx_hh] = df.iloc[i, idx_high]
            # 填充目标行的HC和LH
            df.iloc[a, idx_hc] = df.iloc[a, idx_close]
            df.iloc[a, idx_lh] = df.iloc[a, idx_high]
            # 如果只需要找第一个满足条件的行,就加break;要找所有满足的就去掉
            break

代码说明

  1. 提前初始化新增列,避免后续赋值时出现"列不存在"的错误。
  2. 计算end_idx确保检查范围不超出DataFrame,同时严格限制在当前行之后最多600行。
  3. 用单个值做条件判断,避免布尔Series导致的歧义报错。
  4. 直接通过列索引定位赋值,确保操作准确高效。

内容的提问来源于stack exchange,提问作者Callum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 11:41:03