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

如何对DataFrame所有列使用.apply(lambda x:自定义函数)并解决返回NaN/报错问题

问题诱因

两个异常的核心原因分别如下:

  • apply返回NaN的原因:自定义函数存在参数错位问题,你将df的列(大概率是样本强度值)当作波数数组传入函数,函数用这个错误的「波数数组」生成筛选mask,最终筛选全局变量Zhangfit_output得到的是空数组,np.max运算空数组会直接返回NaN。另外你在函数内固定用全局变量Zhangfit_output作为强度数组,也不符合遍历df每一列计算的需求,相当于所有列的计算都用了同一个强度数据源,逻辑本身就存在错误。
  • applymap报错的原因:applymap是遍历DataFrame的单个元素而非整列/整行,你传入函数的x是单个数值,生成的mask是单个布尔值,筛选数组后得到空数组,np.max无法对空数组执行运算,就抛出zero-size array to reduction operation maximum的错误。

解决方法

首先确认你的DataFrame结构:光谱类数据通常是行索引为波数,每一列对应一个样本的强度值,如果你的数据结构符合该规则,可以按下方步骤修改:

  1. 修正自定义函数,把强度数组、波数数组都作为入参,同时增加空数组判断避免报错:
import numpy as np
def snr_pd(intensity_arr, wavenumber_arr):
    signal_low = 1650
    signal_high = 1750
    noise_low = 1750
    noise_high = 1850

    signal_mask = np.logical_and(wavenumber_arr >= signal_low, wavenumber_arr < signal_high)
    noise_mask = np.logical_and(wavenumber_arr >= noise_low, wavenumber_arr < noise_high)

    # 空值判断,避免无匹配范围时抛出异常
    if intensity_arr[signal_mask].size == 0 or intensity_arr[noise_mask].size == 0:
        return np.nan
    signal = np.max(intensity_arr[signal_mask])
    noise = np.std(intensity_arr[noise_mask])
    return signal / noise
  1. 修改apply调用逻辑,把df的行索引(波数)作为固定参数传入,按列遍历每一个样本的强度数组计算:
# 提取波数数组
wavenumber_arr = df.index.values
# 按列遍历计算信噪比
sd['s/n'] = df.apply(lambda x: snr_pd(x, wavenumber_arr), axis=0)

如果你的DataFrame结构是「列是波数,每一行对应一个样本的强度值」,只需要把apply的axis=0改成axis=1,同时把wavenumber_arr替换为df的列名数组即可:

wavenumber_arr = df.columns.values
sd['s/n'] = df.apply(lambda x: snr_pd(x, wavenumber_arr), axis=1)

额外注意事项

  • 提前检查你的波数范围,确认16501750、17501850两个区间内存在对应波数,否则符合条件的筛选结果为空,依旧会返回NaN。
  • 不要在自定义函数内使用全局变量传递核心计算数据,全局变量的取值容易和预期不符,建议都通过参数传递。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 15:27:02