Python Pandas清洗price列:移除特殊字符且保留小数点
解决Price列清洗的小数点移位与NaN问题
问题根源分析
- 小数点移位原因:你用的
\D正则会匹配所有非数字字符,包括小数点.,导致$9.99被替换成999,转成float后就是999.0。 - NaN生成原因:原
price列混合了float类型数值和带特殊字符的字符串,直接调用str.replace()时,Pandas会对非字符串类型(比如原有的float值)返回NaN,导致整列失效。
正确处理步骤
- 先将整个
price列转为字符串类型,确保所有值都能被字符串方法处理; - 用正则只保留数字和小数点,移除其他特殊字符;
- 处理替换后产生的空字符串或无效值(比如只有小数点),转为NaN;
- 最后转为float类型。
完整代码
import pandas as pd import numpy as np # 原始数据字典 wine_data = { ' country': ['Italy ', 'It aly ', ' $Chile ', 'Sp ain', '$Spain', 'ITALY', '# Chile', ' Chile', 'Spain', ' Italy'], 'price ': [24.99, np.nan, 12.99, '$9.99', 11.99, 18.99, '@10.99', np.nan, '#13.99', 22.99], '#volume': ['750ml', '750ml', 750, '750ml', 750, 750, 750, 750, 750, 750], 'ran king': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 'al cohol@': [13.5, 14.0, np.nan, 12.5, 12.8, 14.2, 13.0, np.nan, 12.0, 13.8], 'total_PHeno ls': [150, 120, 130, np.nan, 110, 160, np.nan, 140, 130, 150], 'color# _INTESITY': [10, np.nan, 8, 7, 8, 11, 9, 8, 7, 10], 'HARvest_ date': ['2021-09-10', '2021-09-12', '2021-09-15', np.nan, '2021-09-25', '2021-09-28', '2021-10-02', '2021-10-05', '2021-10-10', '2021-10-15'] } df = pd.DataFrame(wine_data) # 重命名列(去掉列名的空格,方便后续操作) df.rename(columns={'price ': 'price'}, inplace=True) # 核心清洗逻辑 df['price'] = df['price'].astype(str) # 统一转为字符串类型,避免str方法失效 df['price'] = df['price'].str.replace(r'[^0-9.]', '', regex=True) # 仅保留数字和小数点 df['price'] = df['price'].replace(['', '.'], np.nan) # 处理替换后的无效值为标准NaN df['price'] = df['price'].astype(float) # 转为float类型 # 查看处理结果 print(df['price'])
代码解释
astype(str):把原列的float、NaN统一转成字符串,避免str.replace()对非字符串值返回NaN;[^0-9.]:正则表示只保留数字0-9和小数点,其他所有特殊字符($、#、@等)都会被移除;replace(['', '.'], np.nan):处理替换后可能出现的空字符串(比如原先是NaN转成的'nan'替换后为空)或只有小数点的无效值,转为标准NaN;- 最后转float类型,得到正确的数值格式。
验证结果
处理后price列的值为:
0 24.99 1 NaN 2 12.99 3 9.99 4 11.99 5 18.99 6 10.99 7 NaN 8 13.99 9 22.99 Name: price, dtype: float64
内容的提问来源于stack exchange,提问作者Simon Levi
相关产品推荐
相关产品推荐

