如何解决Pandas读取CSV时含少量非数值项的列被识别为字符串的问题
Pandas读取CSV时混合类型列转数值类型的解决方案
问题场景
使用Pandas读取CSV文件时,某列包含6行数据:其中5行为整数、1行为字符串,导致整列被识别为字符串类型。我已编写代码统计列中int、float、string类型的条目数量,现在需要调整方法,让该列被正确识别为数值类型。
原代码如下:
import pandas as pd import numpy as np def check_type(x, t): return isinstance(x, t) file_path = r"C:\Users\Alireza_Molaei\Desktop\Machine1.csv" df = pd.read_csv(file_path) a, b, c = 0, 0, 0 for column in df.columns: print(f"column: {column}") total_count = df[column].count() if total_count > 0: int_count = df[df[column].apply(check_type, t=(int, np.int64))][column].count() float_count = df[df[column].apply(check_type, t=(float, np.float64))][column].count() str_count = df[df[column].apply(check_type, t=str)][column].count() a += int_count b += float_count c += str_count print(f"int: {int_count}") print(f"float: {float_count}") print(f"string: {str_count}") print("---------------") else: print("There is no data in this column") print(f"int: {a}") print(f"float: {b}") print(f"string: {c}")
解决方法
1. 读取时直接转换(推荐)
利用pd.read_csv结合pd.to_numeric的errors='coerce'参数,将无法转换为数值的字符串转为NaN,让列自动识别为数值类型。
- 针对单个列:
df = pd.read_csv(file_path, converters={'目标列名': lambda x: pd.to_numeric(x, errors='coerce')})
- 批量处理所有列:
df = pd.read_csv(file_path).apply(pd.to_numeric, errors='coerce')
2. 读取后单独转换
如果已经完成CSV读取,可对目标列单独执行类型转换:
# 转换为浮点类型(NaN为浮点类型) df['目标列名'] = pd.to_numeric(df['目标列名'], errors='coerce') # 转换为支持缺失值的整数类型 df['目标列名'] = pd.to_numeric(df['目标列名'], errors='coerce').astype('Int64')
3. 优化类型统计代码
转换后列类型变为数值型,原统计逻辑需要适配Pandas的数值类型(包括支持缺失值的类型),修改后的代码如下:
import pandas as pd import numpy as np file_path = r"C:\Users\Alireza_Molaei\Desktop\Machine1.csv" # 先统一转换列类型 df = pd.read_csv(file_path).apply(pd.to_numeric, errors='coerce') a, b, c = 0, 0, 0 for column in df.columns: print(f"column: {column}") total_count = df[column].count() if total_count > 0: # 统计有效整数(排除NaN) int_count = df[column].apply(lambda x: pd.api.types.is_integer(x) and not pd.isna(x)).sum() # 统计有效浮点数(排除整数和NaN) float_count = df[column].apply(lambda x: pd.api.types.is_float(x) and not pd.isna(x) and not float(x).is_integer()).sum() # 统计剩余字符串(转换后应为0) str_count = df[column].apply(lambda x: isinstance(x, str)).sum() a += int_count b += float_count c += str_count print(f"int: {int_count}") print(f"float: {float_count}") print(f"string: {str_count}") print("---------------") else: print("该列无数据") print(f"总计 int: {a}") print(f"总计 float: {b}") print(f"总计 string: {c}")
内容的提问来源于stack exchange,提问作者ali knl
相关产品推荐
相关产品推荐

