Python 如何用对象中的子字符串替换值?
我有一个纬度数据集中的坐标,每个坐标以一个字母结尾(例如N) 仅检索数字并替换原始值的最佳方法是什么 我的尝试是:Python 如何用对象中的子字符串替换值?,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个纬度数据集中的坐标,每个坐标以一个字母结尾(例如N) 仅检索数字并替换原始值的最佳方法是什么 我的尝试是: raw['LATITUDE'] = raw.loc[(raw['LATITUDE'].str.len() == 9)].str[0:8] 但我收到了一条AttributeError消息 AttributeError: 'DataFrame' object has no attribute 'str' 我还尝试用正则表达式替换这些值,但我不确定如何使其成功 谢谢你的建议 好的,让
raw['LATITUDE'] = raw.loc[(raw['LATITUDE'].str.len() == 9)].str[0:8]
但我收到了一条AttributeError消息
AttributeError: 'DataFrame' object has no attribute 'str'
我还尝试用正则表达式替换这些值,但我不确定如何使其成功
谢谢你的建议
好的,让我们澄清两件事:
apply(type).nunique()
进行确认;它应该大于1:-1
):
尽管您的列是混合数据类型,但这仍然有效,因为str
访问器的设计目的是将非字符串行强制为NaN
如果您希望保留0(我不推荐),请使用快速替换函数,如np.where
raw['LATITUDE'] = np.where(
raw.LATITUDE.eq(0), 0, raw['LATITUDE'].str[:-1].astype(float)
)
raw
LATITUDE
0 0.00000
1 38.72496
2 39.90272
3 38.72927
4 39.91152
5 39.84841
6 0.00000
7 0.00000
8 0.00000
9 39.84941
我不建议保留0s的原因是,从语义上讲,使用NaN来划分缺少的数据比使用0更有意义。在与dtype
对象的系列中,似乎存在混合类型
选项1
您可以先尝试使用errors='concurve'
转换为数值,然后在转换为float
之前,使用所有字符填充NA
:
s = pd.Series(['34.49881N', 0], dtype=object)
s = pd.to_numeric(s, errors='coerce').fillna(s.str[:-1].astype(float))
选项2
你也可以反过来工作。这是不可取的,因为它不太严格,即您可能会在结果中发现意外类型
s = s.str[:-1].astype(float).fillna(s)
结果
在这两种情况下,您都会发现:
print(s)
0 34.49881
1 0.00000
dtype: float64
您可以使用
where
df.LATITUDE.where(df['LATITUDE'].str.len() == 9,df.LATITUDE.str[0:8])
Out[956]:
0 0
1 38.72496
2 39.90272
3 38.72927
4 39.91152
5 39.84841
6 0
7 0
8 0
9 39.84941
Name: LATITUDE, dtype: object
除非您确信您的数据始终只包含一个半球(无南半球纬度),否则我不建议使用子串方法,因为它会将(例如)39.2342N和39.2342S转换为相同的值 相反,我将使用
映射
将字符串转换为一个带有反映半球的符号的数字:
df['Fixed_Lat'] = df['LATITUDE'].map(lambda x: -float(x[:-1]) if x[-1] == 'S' else float(x[:-1]))
这实际上是我的答案,但有不必要的漏洞。选项1做的事情比它需要的要多,选项2和我已经写的差不多,我不同意。使用
s=pd.Series(['34.49881N',0],dtype=object)
测试您的解决方案。混合对象列中的非字符串项被隐式转换为NaN,这简化了很多事情。我想OP只想要纬度,别的什么都不要。我建议从这些NAN开始。s.str[:-1].astype(float)
可以工作,这就是真正需要工作的全部。我不明白你说的“不工作”是什么意思。。。如果你的意思是零消失了,那么是的,那些会变成南,他们应该知道,我不喜欢没有评论的否决票。我已经给你补偿了,祝你愉快。谢谢。你的解释直截了当、简单,而且奏效了。看完你的建议后,我宁愿把所有有争议的行都处理掉。你建议怎么做?@elbertkim你可以简单地按照raw=raw.dropna(subset=['LATITUDE'])
的思路做一些事情。如果您想删除带有NaN的每一行,请选择raw=raw.dropna()
。不客气:)
df['Fixed_Lat'] = df['LATITUDE'].map(lambda x: -float(x[:-1]) if x[-1] == 'S' else float(x[:-1]))