推荐用 pd.to_numeric(..., errors="coerce") 处理混合字符串列,可将非数字值统一转为 NaN 而不报错;astype(float) 遇空值或异常字符会抛 ValueError。

直接用 pd.to_numeric(..., errors="coerce") 转数值,别硬 astype(float)
硬转会炸,不是 Pandas 不够强,而是它拒绝替你做取舍。只要列里混着 "N/A"、""、None 或空格,astype(float) 就抛 ValueError: could not convert string to float。而 pd.to_numeric() 是专为这种场景设计的:它默认只认数字字面量,其余一概变 NaN,不中断、不报错、不猜测。
-
errors="coerce"是清洗阶段唯一推荐的选项;"raise"适合调试定位问题行,"ignore"基本没用 - 加
downcast="integer"可在成功转换后自动降级为int32或int64,省内存 - 如果列里还有嵌套结构(比如
[1, 2]或{"val": 5}),pd.to_numeric会把它也变成NaN——这是对的,先得确认这列“本该是标量”
字符串混合列先查真实类型构成,再决定清洗路径
表面看全是字符串,df["col"].apply(type) 却返回一堆 <class></class>,但 sum() 或 mean() 还是失败?那说明有隐藏的 None、np.nan 或空字符串。它们在 apply(type) 里被跳过或显示为 float,导致误判。
- 用这个检查真实分布:
df["col"].apply(lambda x: type(x).__name__ if pd.notna(x) else "NaN").value_counts() - 常见脏值统一处理:
df["col"] = df["col"].replace(["", "N/A", "NULL", "—", None], np.nan) - 之后再
pd.to_numeric(..., errors="coerce"),就干净了
含单位/结构化文本的列,用 str.extract() 定向捞数字
像 "12.5 kg"、",200.99"、"EA+;123" 这类,不能直接转数值,也不能全当字符串丢掉。得靠正则把数字部分抠出来。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
- 基础提取:
df["col"].str.extract(r"([\d.]+)") # 匹配最前面一串数字或小数 - 带千分位和符号:
df["col"].str.extract(r"([+-]?\d{1,3}(?:,\d{3})*(?:\.\d+)?)") - 命名组更清晰:
df["col"].str.extract(r"(?P<value>[\d.]+)\s*(?P<unit>[a-zA-Z]+)")</unit></value>,返回两列 - 注意:空值或不匹配行会返回
NaN,正好和后续数值转换对齐
源头读入时就控制类型,比事后清洗省力十倍
很多混合列问题根本不用清洗——在 pd.read_csv() 或 pd.read_excel() 那一刻就拦住。
立即学习“Python免费学习笔记(深入)”;
- 强制当字符串读:
dtype={"price": str, "code": str},避免 Pandas 自作主张推断失败 - 提前识别缺失标识:
na_values=["N/A", "", "NULL", "—"] - 关掉默认缺失识别:
keep_default_na=False,防止空字符串被误认为NaN导致整列变object - 读完立刻检查:
df.dtypes和df["col"].sample(5),比跑完清洗才发现错漏快得多
真正难的不是写对一行 pd.to_numeric(),而是判断这一列里哪些值属于业务逻辑上的“有效缺失”,哪些是采集错误,哪些该归为一类异常——这些没法靠函数自动决定,得看业务上下文。

















