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

如何高效移除Pandas DataFrame中包含非数值的行?

高效清理含非数值基因表达数据的DataFrame行

我手上有个存储患者基因表达数据的DataFrame,结构大概是这样:

Patient_ID | gene1 | gene2 | ... | gene10000
    p1       0.142   0.233   ...      bla
    p2       0.243   0.243   ...    -0.364
    ...
    p4000    1.423    bla    ...    -1.222

里面混了不少非数值的噪声值,我需要删掉所有包含非数值的行。之前用下面的代码实现,但跑起来慢得离谱:

cols = df.columns[1:]
df[cols] = df[cols].apply(pd.to_numeric, errors='coerce')
df = df.dropna()

附测试数据复现代码(修正了原代码中行数不匹配的问题):

import numpy as np
import pandas as pd

arr = np.random.random_sample((3000,10000))
df = pd.DataFrame(arr, columns=['gene' + str(i) for i in range(10000)])
df = pd.concat([pd.DataFrame(['p' + str(i) for i in range(3000)], columns=['Patient_ID']),df],axis = 1)
df.loc[2, 'gene0'] = 'bla'
df.loc[4, 'gene9998'] = 'bla'

为什么原代码这么慢?

原代码里的apply(pd.to_numeric)是逐列循环处理,面对10000列的大数据量,循环次数直接拉满,效率自然低。

更高效的实现方案

方案1:堆叠转换(大幅减少循环次数)

把所有基因列堆叠成单个Series,一次性完成数值转换,再还原回原结构。这种方式只需要一次转换操作,而不是10000次:

cols = df.columns[1:]
# 堆叠→批量转换→还原
df[cols] = df[cols].stack().apply(pd.to_numeric, errors='coerce').unstack()
df_clean = df.dropna()

方案2:逐行检测过滤(避免全量转换)

如果不需要保留转换后的数值,只是想过滤掉不合格的行,可以直接逐行检查所有基因列是否都是数值,不用全量转换整个DataFrame,能省不少内存和时间:

cols = df.columns[1:]

def is_numeric(val):
    try:
        float(val)
        return True
    except (ValueError, TypeError):
        return False

# 生成有效行的掩码
valid_rows = df[cols].apply(lambda row: all(is_numeric(x) for x in row), axis=1)
df_clean = df[valid_rows].copy()

方案3:字典推导式逐列转换(比apply更高效)

用字典推导式手动循环列执行pd.to_numeric,比apply的内部循环在大数据量下表现更好:

cols = df.columns[1:]
df[cols] = pd.DataFrame({col: pd.to_numeric(df[col], errors='coerce') for col in cols})
df_clean = df.dropna()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 02:00:38