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
相关产品推荐
相关产品推荐

