
本文介绍如何对 Pandas Series 中的字符串(如 ">3"、"
本文介绍如何对 pandas series 中的字符串(如 `">3"`、`"
在数据清洗中,常遇到含前缀符号(如 , <code>>, , <code>>, ~, ≈)的数值型字符串,需剥离干扰字符、保留核心数字,并将无效值(如 'NA'、空字符串)标准化为 NaN。直接使用 str.replace() 或 str.extract() 配合合理正则可高效解决。
关键在于:仅捕获数字部分(含可选符号和小数点),忽略开头所有非数字前缀,且对非字符串或缺失值保持原状。
推荐使用 Series.str.extract() 而非 replace(..., regex=True),因其语义更清晰、行为更可控:
import pandas as pd
import numpy as np
df = pd.DataFrame({
'col1': [1, np.nan, '>3', 'NA'],
'col2': ["3.", "<5.0", np.nan, 'NA']
})
# 定义正则:匹配行首任意非数字前缀后,首个可选符号+数字+可选小数部分
pattern = r'^[^\w+-\.]*([+-]?\d*\.?\d+)'
# 对每列应用 extract,结果为单列 DataFrame,再用 .squeeze() 转为 Series
# 自动将不匹配项设为 NaN;astype(float) 将字符串数字转为浮点数
for col in df.columns:
df[col] = df[col].astype(str).str.extract(pattern, expand=False).astype(float)
print(df)输出:
col1 col2 0 1.0 3.0 1 NaN 5.0 2 3.0 NaN 3 NaN NaN
✅ 为什么这个正则有效?
-
^锚定行首,确保从前缀开始处理; -
[^\w+-\.]*匹配任意数量的“非数字字符”,但明确排除字母、下划线(\w)、+、-、.—— 这样能跳过、<code>>、等前缀,又不会误吞 <code>+3.14或-2中的合法符号; -
([+-]?\d*\.?\d+)是唯一捕获组:支持带符号、整数、小数(如"3"、"+4.5"、"-.7"),且要求至少一个数字(\d+保证非空); -
str.extract(..., expand=False)返回Series,不匹配时自动填充NaN; -
astype(float)将匹配到的字符串数字转为浮点,同时将原始np.nan和'NA'提取失败后的NaN统一保留。
⚠️ 注意事项:
- 原始
np.nan在.astype(str)后变为字符串'nan',但该字符串不满足数字模式,故仍被正确转为NaN; - 若需支持科学计数法(如
"1e-2"),正则需扩展为r'^[^\w+-\.]*([+-]?(?:\d+\.?\d*|\.\d+)(?:[eE][+-]?\d+)?)'; - 避免使用
replace配合\1的方式:它会尝试替换整个字符串,对不匹配项无默认处理,且易因转义错误(如原问题中的\d未加r'')引发异常; - 如需保留整数类型(非 float),可在最后用
pd.to_numeric(..., downcast='integer')尝试降级,但注意含NaN时 pandas 默认使用float64(因整数型不支持NaN)。
此方法简洁、健壮、可读性强,是处理带符号前缀数值字符串的标准实践。

















