如何对DataFrame的object类型列子集按行求和并忽略文本值?
问题描述
我有一个如下结构的pandas DataFrame:
data = {'ID': ['12AX', '7YTQ','ZA77'], 'Value_1': [19, 'Not applicable', 33], 'Value_2': [13,4,15], 'Value_3': ['Not Applicable', 'Not Applicable', 102.7], 'Status': ['Not Applicable','Not Applicable','Not Applicable'], 'Category': ['AAA', 'AAA', 'BA'] } df = pd.DataFrame(data)
我想新增一列Sum,基于Value_1、Value_2、Value_3三列求和,求和时忽略行中的文本值——比如第一行的Sum应该是19+13=32,直接忽略Value_3里的"Not Applicable"文本。
我写了下面的函数,但它总是返回None或0,找不到问题出在哪:
def safe_sum(row): try: float_numbers = [float(x) for x in row if isinstance(x, (int, float))] return sum(float_numbers) except (ValueError, TypeError): return None df['Sum'] = df[['Value_1','Value_2','Value_3']].apply(safe_sum, axis=1)
请问我哪里出错了?
错误原因与解决办法
问题根源:类型判断失效
你的代码里用isinstance(x, (int, float))筛选数值,但因为Value_1列混合了整数和字符串,DataFrame创建后整列会被统一为object类型——也就是说,原本的整数19在DataFrame里实际是object类型的整数,isinstance(x, (int, float))会返回False,导致筛选出的列表为空,求和结果自然是0;只有遇到无法转换的极端情况才会返回None。
修正后的自定义函数
换个思路:尝试把每个值转成浮点数,成功的就累加,失败的直接跳过:
def safe_sum(row): total = 0.0 for x in row: try: num = float(x) total += num except (ValueError, TypeError): continue return total df['Sum'] = df[['Value_1','Value_2','Value_3']].apply(safe_sum, axis=1)
运行后就能得到正确结果:
| ID | Value_1 | Status | Value_2 | Value_3 | Category | Sum |
|---|---|---|---|---|---|---|
| 12AX | 19 | Not Applicable | 13 | Not Applicable | AAA | 32.0 |
| 7YTQ | Not applicable | Not Applicable | 4 | Not Applicable | AAA | 4.0 |
| ZA77 | 33 | Not Applicable | 15 | 102.7 | BA | 150.7 |
更高效的pandas原生写法
不用自定义函数,直接用pd.to_numeric把目标列转换成数值类型,无法转换的标记为NaN,再按行求和即可:
# 把文本值转为NaN df[['Value_1','Value_2','Value_3']] = df[['Value_1','Value_2','Value_3']].apply(pd.to_numeric, errors='coerce') # 按行求和,自动忽略NaN df['Sum'] = df[['Value_1','Value_2','Value_3']].sum(axis=1)
这种方法更贴合pandas的设计风格,处理大数据量时效率也更高。
内容的提问来源于stack exchange,提问作者A.N.
相关产品推荐
相关产品推荐

