如何在Python Pandas中不使用正则表达式将字符串转为整数?
解决价格字符串转整数(无需正则)的问题
问题背景
我的DataFrame如下:
我尝试了以下两种代码:
car_sales['Price'] = car_sales['Price'].str.replace('[\$\,\.]', '').astype(int)
以及:
car_sales['Price'] = car_sales['Price'].astype(str).str.replace('[\$\,\.]', '').astype(int)
但触发了如下错误:
ValueError: invalid literal for int() with base 10: '$4,000.00'
完整错误栈:
ValueError Traceback (most recent call last) Cell In[87], line 1 ----> 1 car_sales['Price'] = car_sales['Price'].astype(str).str.replace('[\$\,\.]', '').astype(int) 2 car_sales File ~\AppData\Local\Programs\Python\Python310\lib\site-packages\pandas\core\generic.py:6324, in NDFrame.astype(self, dtype, copy, errors) 6317 results = [ 6318 self.iloc[:, i].astype(dtype, copy=copy) 6319 for i in range(len(self.columns)) 6320 ] 6322 else: 6323 # else, only a single dtype is given -> 6324 new_data = self._mgr.astype(dtype=dtype, copy=copy, errors=errors) 6325 return self._constructor(new_data).__finalize__(self, method="astype") 6327 # GH 33113: handle empty frame or series File ~\AppData\Local\Programs\Python\Python310\lib\site-packages\pandas\core\internals\managers.py:451, in BaseBlockManager.astype(self, dtype, copy, errors) 448 elif using_copy_on_write(): 449 copy = False -> 451 return self.apply( 452 "astype", 453 dtype=dtype, 454 copy=copy, 455 errors=errors, 456 using_cow=using_copy_on_write(), 457 ) File ~\AppData\Local\Programs\Python\Python310\lib\site-packages\pandas\core\internals\managers.py:352, in BaseBlockManager.apply(self, f, align_keys, **kwargs) 350 applied = b.apply(f, **kwargs) 351 else: -> 352 applied = getattr(b, f)(**kwargs) 353 result_blocks = extend_blocks(applied, result_blocks) 355 out = type(self).from_blocks(result_blocks, self.axes) File ~\AppData\Local\Programs\Python\Python310\lib\site-packages\pandas\core\internals\blocks.py:511, in Block.astype(self, dtype, copy, errors, using_cow) 491 """ 492 Coerce to the new dtype. 493 (...) 507 Block 508 """ 509 values = self.values -> 511 new_values = astype_array_safe(values, dtype, copy=copy, errors=errors) 513 new_values = maybe_coerce_values(new_values) 515 refs = None File ~\AppData\Local\Programs\Python\Python310\lib\site-packages\pandas\core\dtypes\astype.py:242, in astype_array_safe(values, dtype, copy, errors) 239 dtype = dtype.numpy_dtype 241 try: -> 242 new_values = astype_array(values, dtype, copy=copy) 243 except (ValueError, TypeError): 244 # e.g. _astype_nansafe can fail on object-dtype of strings 245 # trying to convert to float 246 if errors == "ignore": File ~\AppData\Local\Programs\Python\Python310\lib\site-packages\pandas\core\dtypes\astype.py:187, in astype_array(values, dtype, copy) 184 values = values.astype(dtype, copy=copy) 186 else: -> 187 values = _astype_nansafe(values, dtype, copy=copy) 189 # in pandas we don't store numpy str dtypes, so convert to object 190 if isinstance(dtype, np.dtype) and issubclass(values.dtype.type, str): File ~\AppData\Local\Programs\Python\Python310\lib\site-packages\pandas\core\dtypes\astype.py:138, in _astype_nansafe(arr, dtype, copy, skipna) 134 raise ValueError(msg) 136 if copy or is_object_dtype(arr.dtype) or is_object_dtype(dtype): 137 # Explicit copy, or required since NumPy can't view from / to object. -> 138 return arr.astype(dtype, copy=True) 140 return arr.astype(dtype, copy=copy) ValueError: invalid literal for int() with base 10: '$4,000.00'
现寻求不使用正则表达式将价格字符串转为整数的有效方法。
解决方法
方法1:分步替换符号(最直观)
直接逐个清理$、逗号和小数点,先转浮点数再取整,避免因小数位导致的数值偏差:
car_sales['Price'] = ( car_sales['Price'] .str.strip('$') # 移除开头的美元符号 .str.replace(',', '') # 移除千分位逗号 .astype(float) # 转为浮点数 .astype(int) # 转为整数 )
如果确认所有价格都是两位小数,也可以直接移除小数点后转整数:
car_sales['Price'] = ( car_sales['Price'] .str.strip('$') .str.replace(',', '') .str.replace('.', '') .astype(int) )
方法2:用locale模块处理本地化格式
利用系统本地化解析带格式的价格字符串,适合批量处理美式/欧式价格格式:
import locale # 设置美式英语本地化(支持$和千分位逗号) locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') # 解析字符串为浮点数后转整数 car_sales['Price'] = car_sales['Price'].apply(lambda x: int(locale.atof(x.strip('$'))))
注意:若系统未安装en_US.UTF-8本地化,需先安装或替换为系统支持的对应本地化标识。
方法3:手动拆分处理(适配特殊格式)
如果价格格式固定,可手动拆分字符串提取有效数值:
def clean_price(price_str): # 移除$,按小数点拆分取整数部分,再移除逗号 price_part = price_str.replace('$', '').split('.')[0] return int(price_part.replace(',', '')) car_sales['Price'] = car_sales['Price'].apply(clean_price)
内容的提问来源于stack exchange,提问作者n0cuous
相关产品推荐
相关产品推荐

