Pandas 数据框中 str.replace() 的奇怪行为。删除与目标字符串不匹配的值

问题描述 投票:0回答:2

我有一个天气数据的数据框,我正在从 csv 文件中读取该数据框,其中两列“Sea_Level_Pressure”和“Wind_Speed”的数值带有我想删除的后缀“s”。但是当我使用时:

df['Sea_Level_Pressure'] = df['Sea_Level_Pressure'].str.replace('s','')
df['Wind_Speed'] = df['Wind_Speed'].str.replace('s','')

结果是,对于前半行,“Sea_Level_Pressure”值被替换为 null,而在后半行的数据帧中的同一行,“Wind_Speed”值被替换为 null。两列的数据类型都是对象。

这里是示例代码,将从 NOAA 下载 csv 并在应用 str.replace 之前和之后打印 csv。两列的空值中断发生在 2020-09-09 16:52,正如您在输出的第二个 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)

有趣的是,如果我在执行 str.replace 之前将 df 保存到临时 csv,然后将临时 csv 读回 df 并将 str.replace 应用于该数据帧,则它可以正常工作。我尝试在读取 csv 后立即将 str.replace 添加到原始数据帧,并且得到相同的行为,因此几行过滤和重命名列不会导致问题。我还检查了发生中断的日期时间附近的原始 csv 文件,数据中没有任何异常。

提前感谢您的帮助。我对此无计可施。

python python-3.x pandas dataframe replace
2个回答
0
投票

原因是您的列包含混合类型,可能是因为数据在原始 CSV 中的存储方式所致。

print(set([type(x) for x in df['Sea_Level_Pressure']]))

将导致

{float, str}

但是,

str.replace
是一种适用于
str
类型的方法。要解决此问题,请先将列转换为
str
,然后再转换回
float

df = df['Sea_Level_Pressure'].astype(str).str.replace('s','').astype(float)

或者,在导入期间显式指定列的数据类型。


0
投票

基于 csv 文件中的数据,您可以将此代码与 str.extract 一起使用:

import pandas as pd
df = pd.DataFrame({'Sea_Level_Pressure': [29.25, '30.97s', 's23.63']})
df['Sea_Level_Pressure']=df['Sea_Level_Pressure'].astype(str)
df['Sea_Level_Pressure'] = df['Sea_Level_Pressure'].str.extract(r'(\d+\.\d+)').astype(float)
© www.soinside.com 2019 - 2024. All rights reserved.