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

为何在Pandas数据处理中出现RuntimeWarning运行时警告?

Pandas计算出现RuntimeWarning问题排查

1. 数据结构与类型

使用的Pandas DataFrame包含priceNum、volumeNum、deliveryStart、execution、buySell列,其中deliveryStart和execution为UTC时间类型,buySell用于区分买卖方向。

数据类型详情:

priceNum                     float64
volumeNum                    float64
deliveryStart    datetime64[ns, UTC]
execution        datetime64[ns, UTC]
buySell                       object
dtype: object

2. 分组计算逻辑

基于volumeNum列做计算,先按deliveryStart字段分组,将子DataFrame存入字典dfs_dict,执行代码如下:

dfs_dict={k: v for k, v in allOurTrades30min.groupby("deliveryStart")}

for key in dfs_dict:
    sort_df(dfs_dict[key])  
    remaining=calc_remaining(dfs_dict[key])
    
    if remaining<0:
        dfs_dict[key]["weightedOpening"]= (-calc_weighted(dfs_dict[key][dfs_dict[key]["buySell"]=="S"], remaining))
        dfs_dict[key]["remaining"]= remaining
    else:
        dfs_dict[key]["weightedOpening"]= calc_weighted(dfs_dict[key][dfs_dict[key]["buySell"]=="B"], remaining)
        dfs_dict[key]["remaining"]= remaining

3. 问题现象

运行后触发警告:

/opt/conda/lib/python3.7/site-packages/ipykernel_launcher.py:45: RuntimeWarning: invalid value encountered in double_scalars

排查后定位问题出在calc_remaining函数,函数代码如下:

def calc_remaining(df):
    remaining=0.0
    
    for i in range(len(df)):
        if df.iloc[i]["buySell"] == "B":
            remaining = remaining + df.iloc[i]["volumeNum"]
        elif df.iloc[i]["buySell"] == "S": 
            remaining = remaining - df.iloc[i]["volumeNum"]
    
    remaining = round(remaining,3)
    return remaining

部分子DataFrame计算结果正常,但有部分出现NaN异常值,合并后的最终结果也存在异常值。


问题分析与解决方案

可能的触发原因

  1. 空分组DataFrame:部分分组后的子DataFrame无数据,循环不执行,后续调用calc_weighted时传入空数据引发计算异常
  2. 字段异常值:buySell列存在非"B"/"S"的值(如NaN),或volumeNum列存在空值,导致加减操作后remaining变为NaN
  3. 循环逻辑缺陷:逐行循环的方式无法高效处理空值与异常行,容易遗漏边界场景

优化后的calc_remaining函数

用Pandas向量化操作替代循环,同时加入异常值过滤:

def calc_remaining(df):
    # 过滤无效行:仅保留buySell为B/S、volumeNum非空的记录
    valid_rows = df[(df["buySell"].isin(["B", "S"])) & (df["volumeNum"].notna())]
    if valid_rows.empty:
        return 0.0
    # 向量化计算:B对应加volumeNum,S对应减volumeNum
    total = valid_rows.apply(lambda row: row["volumeNum"] if row["buySell"] == "B" else -row["volumeNum"], axis=1).sum()
    return round(total, 3)

增加防御性检查

在主循环中加入空数据检查,避免后续函数处理无效输入:

import pandas as pd

for key in dfs_dict:
    df = dfs_dict[key]
    sort_df(df)
    
    # 处理空分组
    if df.empty:
        df["weightedOpening"] = None
        df["remaining"] = 0.0
        continue
        
    remaining = calc_remaining(df)
    
    # 处理remaining为NaN的情况
    if pd.isna(remaining):
        df["weightedOpening"] = None
        df["remaining"] = 0.0
        continue
        
    if remaining < 0:
        sell_subset = df[df["buySell"] == "S"]
        df["weightedOpening"] = -calc_weighted(sell_subset, remaining) if not sell_subset.empty else None
    else:
        buy_subset = df[df["buySell"] == "B"]
        df["weightedOpening"] = calc_weighted(buy_subset, remaining) if not buy_subset.empty else None
        
    df["remaining"] = remaining

优化说明

  • 向量化操作比逐行循环更高效,同时能自动规避部分空值问题
  • 提前过滤无效行,确保计算基于有效数据
  • 增加多层空数据检查,避免因空输入触发计算异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 15:00:49