【问题标题】:Pandas remove rows which any string熊猫删除任何字符串的行
【发布时间】:2017-02-12 02:05:31
【问题描述】:

一个非常基本的 qs 家伙 - 比 vm 看看。我想删除 Col1 中包含任何字符串的行 - 只关心 Col1 中的数值。

输入:

      Col1  Col2 Col3
0      123  48.0  ABC
1       45  85.0  DEF
2    A.789  66.0  PQR
3    RN.35   9.0  PQR
4      LMO  12.0  ABC

输出:

      Col1  Col2 Col3
0    123.0  48.0  ABC
1     45.0  85.0  DEF

我试过了

test = input_[input_['Col1'].str.contains(r'ABCDEGGHIJKLMNOPQRSTUVWXYZ.')]

但是看到这个错误

ValueError: 无法使用包含 NA / NaN 值的向量进行索引

你能:

  • 简要解释一下为什么这不起作用?
  • 请问替代解决方案是什么?

【问题讨论】:

    标签: python string pandas indexing numeric


    【解决方案1】:

    另一个更快的解决方案boolean indexingto_numeric 条件,其中参数errors='coerce' 表示如果数据不是数字,则转换为NaN - 所以你需要通过notnull 找到所有不是NaN 的数据:

    print (pd.to_numeric(df.Col1, errors='coerce'))
    0    123.0
    1     45.0
    2      NaN
    3      NaN
    4      NaN
    Name: Col1, dtype: float64
    
    print (pd.to_numeric(df.Col1, errors='coerce').notnull())
    0     True
    1     True
    2    False
    3    False
    4    False
    Name: Col1, dtype: bool
    
    df = df[pd.to_numeric(df.Col1, errors='coerce').notnull()]
    print (df)
      Col1  Col2 Col3
    0  123  48.0  ABC
    1   45  85.0  DEF
    

    时间安排

    #[100000 rows x 3 columns]    
    df = pd.concat([df]*10000).reset_index(drop=True)
    
    In [16]: %timeit (df.ix[df.Col1.map(lambda x: re.compile("[a-zA-Z]+").search(x) is None)])
    10 loops, best of 3: 57.7 ms per loop
    
    In [17]: %timeit (df[pd.to_numeric(df.Col1, errors='coerce').notnull()])
    10 loops, best of 3: 22 ms per loop
    
    In [18]: %timeit (df[~df['Col1'].astype(str).str.contains(r'[ABCDEGGHIJKLMNOPQRSTUVWXYZ.]', na=False)])
    10 loops, best of 3: 38.8 ms per loop
    

    您的解决方案:

    我认为您需要通过astype 转换为str,然后添加[] used to indicate a set of characters 和最后添加参数na=False 因为似乎一些NaN 值在col1 中,然后转换为False:

    print (df['Col1'].astype(str).str.contains(r'[ABCDEGGHIJKLMNOPQRSTUVWXYZ.]', na=False))
    0    False
    1    False
    2     True
    3     True
    4     True
    Name: Col1, dtype: bool
    

    然后需要通过~ 反转布尔掩码并使用boolean indexing

    print (df[~df['Col1'].astype(str).str.contains(r'[ABCDEGGHIJKLMNOPQRSTUVWXYZ.]', na=False)])
      Col1  Col2 Col3
    0  123  48.0  ABC
    1   45  85.0  DEF
    

    【讨论】:

    • 我还添加了您的解决方案的时间安排,什么是公认的解决方案更快;)
    【解决方案2】:

    这样做:

    import re
    regex = re.compile("[a-zA-Z]+")
    df.ix[df.col1.map(lambda x: regex.search(x) is None)]
    

    【讨论】:

    • 所以我这样做了:'input_.ix[input_.Col1.map(lambda x: regex.search(x) is None)]' 并得到错误:'TypeError: expected string or buffer '
    • 因为我不知道 col1 的类型,所以我认为它是字符串并执行该过程。如果不是,它将引发此类异常。您可以这样做: df.ix[df.col1.map(lambda x: regex.search(str(x)) is None)] 将 col1 转换为字符串类型并再次运行。
    • 轰隆隆!做到了-谢谢vm..请问为什么我的方法行不通?
    • 我推荐的是的书。我们不需要深入挖掘为什么它是错误的,我们只需要知道如何以正确的方式去做。
    猜你喜欢
    • 2021-11-28
    • 1970-01-01
    • 2016-10-21
    • 2018-12-12
    • 2023-01-11
    • 2021-03-16
    • 2020-02-25
    • 2019-03-15
    • 2021-09-25
    相关资源
    最近更新 更多