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

如何对含零及小于1值的行运行scipy.stats.gmean并解决报错

问题根因

报错和结果不符合预期的核心原因有3个:

  • 数据类型异常:原始数据第四行GSM774列的值为字符串格式的00000000,导致所有数值列被自动识别为字符串(object)类型,scipy.stats.gmean计算时需要对数值取对数,无法处理字符串类型,直接触发类型报错。
  • 列切片范围错误:代码中使用df.iloc[:,1:5]做切片,pandas的iloc切片为左闭右开规则,仅选中了GSM772到GSM775共4列,漏掉了最后一列GSM776,计算范围不符合要求。
  • 未实现自定义计算规则:原生scipy.stats.gmean不会自动判定行内是否存在零值,无法满足「行内存在零值则几何均值直接记为0」的要求。
最优解决方法

先清洗数据类型,再实现自定义的按行计算逻辑,完整可运行代码如下:

import pandas as pd
import numpy as np
from scipy.stats import gmean

# 第一步:清洗数据类型,将所有GSM样本列转为浮点型,非法值统一转为0
# 先将基因名列设为索引,避免类型转换影响基因名
df = df.set_index('#Gene')
# 对所有列做数值转换,无法解析的值转为NaN后填充为0
df = df.apply(pd.to_numeric, errors='coerce').fillna(0)

# 第二步:按规则逐行计算几何均值
def row_gmean_calc(row):
    # 行内存在任意0值,直接返回0
    if (row == 0).any():
        return 0.0
    # 无零值时正常计算几何均值
    return gmean(row)

# 将计算结果追加为新列
df['GeometricMean'] = df.apply(row_gmean_calc, axis=1)

# 如需把基因名从索引还原为普通列,执行下行代码即可
df = df.reset_index()

# 打印验证结果
print(df)
额外说明
  • 原代码中重复调用2次scipy.stats.gmean属于冗余计算,无实际作用可删除。
  • 类型转换步骤会自动把类似00000000的字符串格式数字转为合法数值,无需手动逐行替换脏值。
  • 计算逻辑严格匹配需求:只要行内存在零值直接返回0,无零值时对整行所有值计算几何均值,不会错误纳入零值参与对数计算。

内容的提问来源于stack exchange,提问作者TraPS-VarI

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 00:21:54