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

Python中使用<比较时apply函数返回异常结果的问题

问题描述

当使用>比较Fechamento和BBANDS ACIMA时,代码运行完全正常;但把比较符号改成<后,apply函数返回的DataFrame丢失原有列,只剩列名为0的列,且每个单元格都是Series对象。

正常运行的代码

def filtrar_tempo_candles(row):
    if pd.notna(row['Proxima_Hora']) and pd.notna(row['Hora_anterior']):
        if row['Proxima_Hora'] - row['Hora'] >= pd.Timedelta(hours=1):
            return row
        else:
            return None
    if row['Proxima_Hora'] - row['Hora'] >= pd.Timedelta(hours=1):
        return row
    
    if row['Hora_anterior'] - row['Hora'] <= pd.Timedelta(hours=1):
        return row
        
    if row['Sozinho'] ==1:
        return row


df_indice_5 = df_indice_5.loc[(df_indice_5["Diff_corr_banda"].between(10,21)) &
                                  (df_indice_5['Fechamento'] > df_indice_5['BBANDS ACIMA'])]

df_indice_5_final = df_indice_5.apply(filtrar_tempo_candles,axis=1,result_type='expand')

出现异常的代码

df_indice_5 = df_indice_5.loc[(df_indice_5["Diff_corr_banda"].between(10,21)) &
                                  (df_indice_5['Fechamento'] < df_indice_5['BBANDS ACIMA'])]

df_indice_5_final = df_indice_5.apply(filtrar_tempo_candles,axis=1,result_type='expand')

原因分析

问题核心在filtrar_tempo_candles函数的返回值逻辑和pandas的自动推断机制:

  • 用>过滤时,函数对多数行返回完整的row(Series类型),少数返回None,pandas能自动拼接这些row形成和原表结构一致的DataFrame,返回None的行直接被丢弃。
  • 用<过滤后,可能出现所有行都触发函数返回None,或者返回的有效row占比极低,导致pandas无法推断原表的列结构。此时apply会把每个返回值(包括None)包装成单个元素的Series,最终形成只有列0的异常结构。

另外函数本身存在逻辑漏洞:如果Proxima_Hora和Hora_anterior都为空,且Sozinho不等于1时,函数没有明确返回值,默认返回None,这也会加剧结果异常的概率。

解决方法

1. 修复函数返回逻辑

确保函数对所有行都有明确的返回值,避免无返回的情况:

def filtrar_tempo_candles(row):
    if pd.notna(row['Proxima_Hora']) and pd.notna(row['Hora_anterior']):
        if row['Proxima_Hora'] - row['Hora'] >= pd.Timedelta(hours=1):
            return row
        else:
            return None
    # 新增空值判断,避免空值参与计算报错
    if pd.notna(row['Proxima_Hora']) and (row['Proxima_Hora'] - row['Hora'] >= pd.Timedelta(hours=1)):
        return row
    
    if pd.notna(row['Hora_anterior']) and (row['Hora_anterior'] - row['Hora'] <= pd.Timedelta(hours=1)):
        return row
        
    if row['Sozinho'] == 1:
        return row
    # 明确默认返回值
    return None

2. 提前过滤无效行

在调用apply前,先处理关键列的空值,减少函数内的复杂判断:

# 过滤掉Proxima_Hora和Hora_anterior全为空的行(根据业务需求调整)
df_indice_5 = df_indice_5.dropna(subset=['Proxima_Hora', 'Hora_anterior'], how='all')

3. 改用向量化操作替代apply

apply效率低且易出现结构推断问题,推荐用向量化条件直接过滤行:

# 构建各个过滤条件
cond1 = (pd.notna(df_indice_5['Proxima_Hora'])) & (pd.notna(df_indice_5['Hora_anterior'])) & \
        (df_indice_5['Proxima_Hora'] - df_indice_5['Hora'] >= pd.Timedelta(hours=1))
cond2 = (pd.notna(df_indice_5['Proxima_Hora'])) & \
        (df_indice_5['Proxima_Hora'] - df_indice_5['Hora'] >= pd.Timedelta(hours=1))
cond3 = (pd.notna(df_indice_5['Hora_anterior'])) & \
        (df_indice_5['Hora_anterior'] - df_indice_5['Hora'] <= pd.Timedelta(hours=1))
cond4 = (df_indice_5['Sozinho'] == 1)

# 合并所有条件,直接过滤得到结果
final_cond = cond1 | cond2 | cond3 | cond4
df_indice_5_final = df_indice_5[final_cond]

内容的提问来源于stack exchange,提问作者murilo xavier de souza

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 15:52:35