You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 22:07:44