如何用pandas对象中的子串替换值?

时间:2018-04-22 22:02:21

标签: python pandas dataframe

我在Latitude数据集中有坐标,每个坐标都有一个字母(例如N)。

仅检索数字并替换原始值的最佳方法是什么?

我的尝试是:

raw['LATITUDE'] = raw.loc[(raw['LATITUDE'].str.len() == 9)].str[0:8]

但是我收到了一条AttributeError消息。

AttributeError: 'DataFrame' object has no attribute 'str'

我也尝试用正则表达式替换值,但我不确定如何使其成功。

我很感激任何建议,谢谢。

enter image description here

4 个答案:

答案 0 :(得分:5)

好的,让我们澄清一些事情:

  1. 您似乎正在使用混合dtypes。打印raw['LATITUDE'].apply(type).nunique()进行确认;它应该是> 1。

  2. 您正在使用地理数据。很多你的价值都是无效的(0),我建议将其强制转换为NaN,因为它代表了更有意义的缺失数据

  3. 要解决您的问题,请尝试将所有内容添加到最后一个字符(:-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]))