当前位置: 首页 > 面试题库 >

Python-pandas过滤串联的多个子串

裴姚石
2023-03-14
问题内容

我需要过滤pandas数据帧中的行,以便特定的字符串列包含提供的子字符串列表中的至少一个。子字符串可能具有不寻常的/正则表达式字符。比较不应该涉及正则表达式,并且不区分大小写。

例如:

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则我们不必测试该行的任何后续字符串。


问题答案:

如果你坚持使用纯熊猫,那么出于性能和实用性的考虑,我认为你应该使用正则表达式来完成此任务。但是,你将需要首先适当地转义子字符串中的任何特殊字符,以确保它们在字面上匹配(并且不用作正则表达式元字符)。

这很容易做到re.escape

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

然后可以使用正则表达式管道将这些转义的子字符串连接起来|。可以对照字符串检查每个子字符串,直到找到一个匹配项(或它们都已经过测试)。

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

然后,掩蔽阶段将成为遍历各行的单个低级循环:

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

这是一个简单的设置,可以让你感受到性能:

from random import randint, seed

seed(321)

# 100 substrings of 5 characters
lst = [''.join([chr(randint(0, 256)) for _ in range(5)]) for _ in range(100)]

# 50000 strings of 20 characters
strings = [''.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秒(因此,一百万行最多可能需要20秒):

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

使用相同的输入数据,问题中的方法花费了大约5秒钟。

值得注意的是,在没有匹配的情况下,这些时间是“最坏的情况”(因此检查了所有子字符串)。如果有比赛,则计时会有所改善。



 类似资料:
  • 问题内容: 我正在做熊猫分析。 我的表有700万行* 30列。单元格值的范围从-1到3随机。现在,我想根据列的值过滤掉行。 我了解如何根据多个条件进行选择,写下条件并通过“&”“ |”组合。 但是我有30列要过滤,并按相同的值过滤。例如,需要选择最后12列的值等于-1 上面的代码给了我一个布尔值。我需要实际的数据框。 这里的逻辑是“或”,表示如果任何列的值为-1,则需要选择该行。另外,很高兴知道我

  • 我有一个带有一列字符串值的pandas DataFrame。我需要根据部分字符串匹配来选择行。 类似于这个成语 返回布尔值。我熟悉的语法,但似乎找不到一种方法来处理部分字符串匹配,比如。

  • 问题内容: 我正在研究AngularJS教程,并了解的基础知识 但是,开箱即用的实现似乎仅限于将项目列表过滤为输入的确切单词或短语。 示例:如果查询是“ table cloth”,则结果列表可以包含带有短语“ Decorative table cloth”的结果,但由于过滤器只是一个连续的搜索字符串,因此将不包括“ Table fortable装饰布”。 我知道可以添加自定义过滤器,但乍一看似乎主

  • 问题内容: 有什么方法可以使用两个列的串联来过滤模型吗?我的模型是这样的: 我需要的是在两列连接之后进行过滤,如果用户输入A123,我希望能够找到具有系列和数字的任何项,例如%A和123%或%A1和23% django模型?还是有可能使用原始sql?我宁愿不使用串联构造一个新列。 问题答案: 是的,那是可能的;您需要将QuerySet与字段串联在一起,并且新的“虚拟”列将能够进行过滤。 有关过滤注

  • 问题内容: 例如,我有下表: 分组后: 我需要的是删除每个组中的行,其中列中的数量小于组中column的所有行中的最大值。好吧,我在将这个问题翻译和表达为英语时遇到了问题,因此这里是示例: 组中列中的行的最大值: 8 所以我想删除带有索引的行,并保留带有索引的行, 组中列中的行的最大值: 5 所以我想删除带有索引的行并保留带有索引的行 我尝试使用熊猫过滤器功能,但是问题是它一次在组中的所有行上运行

  • 问题内容: 我正在尝试使用作为df一部分的几个布尔变量来过滤df,但一直未能做到。 样本数据: C和D列的dtype是布尔值。我想仅使用C或D为True的行创建一个新的df(df1)。它看起来应该像这样: 我已经尝试过类似的事情,因为它无法处理布尔类型,因此会遇到问题: 有任何想法吗? 问题答案: In [82]: d Out[82]: A B C D 0 John Doe 45 True Fal