Pandas中str.replace()异常:非目标值被误置为空问题求助
问题与解决方案
问题:从NOAA的CSV读取气象数据到Pandas DataFrame后,执行df['Sea_Level_Pressure'] = df['Sea_Level_Pressure'].str.replace('s','')和df['Wind_Speed'] = df['Wind_Speed'].str.replace('s','')移除后缀's'时出现异常:前半部分行的Sea_Level_Pressure值变为空,后半部分行的Wind_Speed值变为空,两列数据类型均为object。保存DataFrame为CSV再重新读取后执行替换,结果正常。
可复现代码:
import pandas as pd url = 'https://www.ncei.noaa.gov/data/local-climatological-data/access/2020/72530594892.csv' df = pd.read_csv(url) df = df[df.REPORT_TYPE == 'FM-15'] df = df[['DATE', 'HourlyDryBulbTemperature','HourlyRelativeHumidity','HourlySeaLevelPressure','HourlyWindSpeed','HourlyPrecipitation']] df.rename(columns={'HourlyDryBulbTemperature': 'Temp_F', 'HourlyRelativeHumidity':'Rel_Humidity', 'HourlySeaLevelPressure':'Sea_Level_Pressure','HourlyWindSpeed':'Wind_Speed','HourlyPrecipitation':'Precip'}, inplace=True) df.to_csv('weather_bf_replace.csv', index=False) df['Sea_Level_Pressure'] = df['Sea_Level_Pressure'].str.replace('s','') df['Wind_Speed'] = df['Wind_Speed'].str.replace('s','') df.to_csv('weather_after_replace.csv',index=False)
原因分析
原数据中,Sea_Level_Pressure和Wind_Speed列同时存在数值类型(无's'后缀)和字符串类型(带's'后缀)的混合数据。Pandas的str.replace方法仅对字符串类型生效,非字符串类型(如数值、NaN)调用该方法会直接返回NaN,导致部分行数据丢失。而保存再读取CSV的过程中,所有数据会被统一转为字符串类型,因此替换操作能正常执行。
解决方案
方案1:先将列转为字符串类型再替换
先强制把列转成字符串,确保所有行都能被str.replace处理,之后可根据需求转为数值类型:
# 处理Sea_Level_Pressure df['Sea_Level_Pressure'] = df['Sea_Level_Pressure'].astype(str).str.replace('s', '', regex=False) # 处理Wind_Speed df['Wind_Speed'] = df['Wind_Speed'].astype(str).str.replace('s', '', regex=False) # 可选:将列转为数值类型(空值会转为NaN) df['Sea_Level_Pressure'] = pd.to_numeric(df['Sea_Level_Pressure'], errors='coerce') df['Wind_Speed'] = pd.to_numeric(df['Wind_Speed'], errors='coerce')
方案2:使用apply处理混合类型数据
通过apply判断每个元素的类型,仅对字符串执行替换操作:
def remove_s_suffix(x): if isinstance(x, str): return x.replace('s', '') return x df['Sea_Level_Pressure'] = df['Sea_Level_Pressure'].apply(remove_s_suffix) df['Wind_Speed'] = df['Wind_Speed'].apply(remove_s_suffix)
方案3:读取CSV时指定列类型为字符串
在read_csv阶段就指定目标列为字符串类型,从根源避免混合类型问题:
df = pd.read_csv(url, dtype={'HourlySeaLevelPressure': str, 'HourlyWindSpeed': str}) # 后续过滤、重命名操作不变 df = df[df.REPORT_TYPE == 'FM-15'] df = df[['DATE', 'HourlyDryBulbTemperature','HourlyRelativeHumidity','HourlySeaLevelPressure','HourlyWindSpeed','HourlyPrecipitation']] df.rename(columns={'HourlyDryBulbTemperature': 'Temp_F', 'HourlyRelativeHumidity':'Rel_Humidity', 'HourlySeaLevelPressure':'Sea_Level_Pressure','HourlyWindSpeed':'Wind_Speed','HourlyPrecipitation':'Precip'}, inplace=True) # 直接执行替换 df['Sea_Level_Pressure'] = df['Sea_Level_Pressure'].str.replace('s','') df['Wind_Speed'] = df['Wind_Speed'].str.replace('s','')
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

