我在Latitude数据集中有坐标,每个坐标都有一个字母(例如N)。
仅检索数字并替换原始值的最佳方法是什么?
我的尝试是:
raw['LATITUDE'] = raw.loc[(raw['LATITUDE'].str.len() == 9)].str[0:8]
但是我收到了一条AttributeError消息。
AttributeError: 'DataFrame' object has no attribute 'str'
我也尝试用正则表达式替换值,但我不确定如何使其成功。
我很感激任何建议,谢谢。
答案 0 :(得分:5)
好的,让我们澄清一些事情:
您似乎正在使用混合dtypes。打印raw['LATITUDE'].apply(type).nunique()
进行确认;它应该是> 1。
您正在使用地理数据。很多你的价值都是无效的(0),我建议将其强制转换为NaN,因为它代表了更有意义的缺失数据
要解决您的问题,请尝试将所有内容添加到最后一个字符(:-1
):
raw['LATITUDE'] = raw['LATITUDE'].str[:-1].astype(float)
raw
LATITUDE
0 NaN
1 38.72496
2 39.90272
3 38.72927
4 39.91152
5 39.84841
6 NaN
7 NaN
8 NaN
9 39.84941
尽管你的列是混合dtypes,但仍然有效,因为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
我不建议保留0的原因是因为使用NaN划分缺失数据而不是0来在语义上更有意义。
答案 1 :(得分:4)
您的系列中似乎有dtype object
的混合类型。
选项1
您可以先转换为数字errors='coerce'
,然后fillna
转换为最后一个字符,然后转换为float
:
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
答案 2 :(得分:1)
您可以使用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
答案 3 :(得分:0)
除非您确信您的数据始终只包含一个半球(没有南半球),否则我不推荐使用子串方法,因为它会将(例如)39.2342N和39.2342S转换为相同的值。
相反,我会使用map
将字符串转换为带有反映半球的符号的数字:
df['Fixed_Lat'] = df['LATITUDE'].map(lambda x: -float(x[:-1]) if x[-1] == 'S' else float(x[:-1]))