熊猫删除任何字符串的行

Posted

技术标签:

【中文标题】熊猫删除任何字符串的行【英文标题】: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 值的向量进行索引

你能:

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

【问题讨论】:

【参考方案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..请问为什么我的方法行不通? 我推荐的是的书。我们不需要深入挖掘为什么它是错误的,我们只需要知道如何以正确的方式去做。

以上是关于熊猫删除任何字符串的行的主要内容,如果未能解决你的问题,请参考以下文章

熊猫选择列中的值不以字符串开头的行

删除熊猫数据框中具有特定值的行[重复]

如何知道使用熊猫删除的行数

如何从包含特定列中特定字符串的熊猫数据框中删除行? [复制]

熊猫数据框可以有列表的dtype吗?

删除熊猫中多列中包含一段字符串的所有行