为了账号安全,请及时绑定邮箱和手机立即绑定

熊猫对串联多个子串的过滤

熊猫对串联多个子串的过滤

侃侃无极 2019-06-29 10:35:05
我需要在pandas数据格式,以便特定的字符串列至少包含一个提供的子字符串列表中的一个。子字符串可能具有不寻常的/正则字符。比较不应涉及regex,而且不区分大小写。例如:lst = ['kdSj;af-!?', 'aBC+dsfa?\-', 'sdKaJg|dksaf-*']我现在用的口罩是这样的:mask = np.logical_or.reduce([df[col].str.contains(i, regex=False, case=False) for i in lst])df = df[mask]我的数据很大(~1mio行)和lst长度是100。有没有更有效的方法?例如,如果lst,我们就不必测试该行的任何后续字符串。熊猫对串联多个子串的过滤
查看完整描述

3 回答

?
FFIVE

TA贡献1797条经验 获得超6个赞

如果你坚持使用纯熊猫,无论是性能还是实用性,我认为你对此任务使用regex。但是,您需要首先正确地转义子字符串中的任何特殊字符,以确保它们确实匹配(而不是用作regex元字符)。

这很容易使用re.escape:

>>> import re>>> esc_lst = [re.escape(s) for s in lst]

然后,可以使用regex管道连接这些转义子字符串。|..每个子字符串都可以根据字符串进行检查,直到其中一个匹配为止(或者它们都已经过测试)。

>>> pattern = '|'.join(esc_lst)

然后,掩蔽阶段通过行变成一个单一的低级别循环:

df[col].str.contains(pattern, case=False)

下面是一个获得性能感觉的简单设置:

from random import randint, seed

seed(321)# 100 substrings of 5 characterslst = [''.join([chr(randint(0, 256)) for _ in range(5)]) for _ in range(100)]# 50000 strings of 20 charactersstrings = [''.join([chr(randint(0, 256)) for _ in range(20)]) for _ in range(50000)]col = pd.Series(strings)esc_lst = [re.escape(s) for s in lst]pattern = '|'.join(esc_lst)

所提出的方法大约需要1秒(因此,100万行可能需要20秒):

%timeit col.str.contains(pattern, case=False)1 loop, best of 3: 981 ms per loop

问题中的方法使用相同的输入数据大约需要5秒。

值得注意的是,这些时候是“最糟糕的情况”,因为没有匹配(所以检查子串)。如果有比赛时间更好的比赛。


查看完整回答
反对 回复 2019-06-29
?
智慧大石

TA贡献1946条经验 获得超3个赞

使用更简单的例子&忽略案例(大写或小写)

过滤和获取二进制向量:

我想找到pd.Seriesv,包含“at”或“Og”。如果元素包含模式,则获取1;如果不包含模式,则获取0。

我会用re:

import re

我的载体:

v=pd.Series(['cAt','dog','the rat','mouse','froG'])[Out]:0        cAt1        dog2    the rat3      mouse4       froG

我想找到包含“at”或“Og”的所有v元素。这是,我可以定义我的pattern作为:

pattern='at|Og'

因为我想要一个带有1s的向量,如果项目包含模式,则为0。

我创建了一个长度与v相同的酉向量:

v_binary=[1]*len(v)

我得到了一个s那是True如果一个元素v包含patternFalse如果它不包含它。

s=v.str.contains(pattern, flags=re.IGNORECASE, regex=True)

若要获得二进制向量,请将v_binary*s:

v_binary*s[Out]0    11    12    13    04    1


查看完整回答
反对 回复 2019-06-29
  • 3 回答
  • 0 关注
  • 450 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信