Pandas:如何从一列中删除数字和特殊字符

1 人关注

我试图从一列中删除除字母和空格以外的所有字符,但当我使用代码来执行同样的操作时,它给出的输出是 'nan' ,而不是 NaN (空值)。

数据输入。

ABC ad YQW \2 AQ4 GH

Expected output:

ABC ad AQ GH

我一直在使用的代码。

df['col1'] = df['col1'].astype(str).str.extract(r'([A-Za-z]+(?: [A-Za-z]+)*)')

后来我用这一列来检查NaN的条件,但它没有给出,因为在执行上述脚本后,它把NaN的值改为'nan'

注意:如果不通过.astype(str)将其转换为字符串,我的数据将得到

AttributeError:只能对字符串值使用.str访问器!

5 个评论
Manz
@HenryEcker - 使用建议给出的错误:"AttributeError。只能对字符串值使用.str访问器!"
smci
因为你的数据类型在那一列上被打乱了:你在读入时得到了NA,所以它不是'字符串'而是'对象'类型。回到 [pd.read_csv](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html)/read_excel() 命令。将该列的dtype设置为 "字符串"。 pd.read_csv(..., dtype={'col1': 'string'}) 。如果你需要,还可以定义选项 na_values = ...
smci
并在读取后使用 df.info() ,以确保所有列都有你期望的dtype。这里他们没有。代码 df['col1'].astype(str)... 是一个提示。
请注意,我们在这里不能使用 .extract() ,必须使用 .replace() 来摆脱不需要的字符。像'ab c1d2@ ef4'这样的字符串如何处理?使用什么样的重码模式才能只提取字母和空格,而留下数字和特殊字符?别忘了,我们必须考虑一般情况,而不仅仅是这里的样本数据。我们能不能在这里引用所有可能的regex模式来处理这种字母、空格、数字和特殊字符模式的无限数量的组合?
python
pandas
Manz
Manz
发布于 2021-05-29
2 个回答
wwnde
wwnde
发布于 2021-05-29
已采纳
0 人赞同

另一种方法是提取字母数字,但不包括数字。见下面的代码

df['col1']=df['col1'].str.extract('(\w+\s\w+[^0-9]|\w+[^0-9])')
0  ABC ad
1    YQW 
2  AQ4 GH
3     NaN
4     NaN
5     NaN
    
我有一些瑞典语的数据,你的代码运行良好,但也删除了Å、Ä、Ö(å、ä、ö),但我想保留它们。如何修改你的代码以保留它们?
SeaBean
SeaBean
发布于 2021-05-29
0 人赞同

你可以通过以下步骤进行。

  • Firstly, replace NaN value by empty string (which we may also get after removing characters and will be converted back to NaN afterwards).
  • Cast the column to string type by .astype(str) for in case some elements are non-strings in the column.
  • Replace non alpha and non blank to empty string by str.replace() with regex
  • Finally, replace empty string to NaN by .replace()
  • (注:前两步是为了特别处理OP的 AttributeError: Can only use .str accessor with string values! 的问题,尽管我测试了特别添加整数和浮点数(不是字符串中的整数和浮点数,而是真实的数字值),也没有得到前两步的问题。也许是其他一些特殊的数据类型!)。 其他没有同样问题的用户可以只使用最后两步,从 str.replace() 开始。

    df['col1'] = df['col1'].fillna('').astype(str).str.replace(r'[^A-Za-z ]', '', regex=True).replace('', np.nan, regex=False)
    

    Result:

    print(df)
    0  ABC ad
    1    YQW 
    2   AQ GH
    3     NaN
    4     NaN