我在python中有两个数组。一个包含一个字符串列表,我想使用这个列表中的每个字符串在另一个数组中进行搜索,如果这个字符串作为子字符串包含在另一个数组中。
result_list = []
array_1 = np.array(['ab', 'fo', 'ba']) # just as a veeeery easy example
array_2 = np.array(['lab', 'abc', 'zwf', 'foo', 'bar'])
for word_to_search in array_1:
for potential_word in array_2:
if word_to_search in potential_word:
result_list.append(potential_word)
result_list = list(set(result_list)) # delete duplicates
# result_list = ['lab', 'abc', 'foo', 'bar']我在基本的python列表和numpy数组中尝试过。由于性能原因,后者要好得多,但我仍然认为必须有更好的解决方案。
因为我的array_1大约有11,000,000个条目,而我的array_2大约有300,000个条目,所以我需要有一个非常高性能的方法,这不是我目前的解决方案的情况……
发布于 2021-03-23 04:58:05
在步骤result.append(potential_word)之后,你可以跳出for循环,这样你就不会有重复的东西,而且肯定会节省时间。此外,您还需要更改for循环的顺序,外部循环通过array_2循环,内部循环通过array_1循环。
import numpy as np
result_list = []
array_1 = np.array(['ab', 'fo', 'ba'])
array_2 = np.array(['lab', 'abc', 'zwf', 'foo', 'bar'])
for potential_word in array_2:
for word_to_search in array_1:
if word_to_search in potential_word:
result_list.append(potential_word)
break
print(result_list)发布于 2021-03-23 05:06:58
您可以使用现有的短路方法any和all;在这里,您只需要any。
result_list = [word for word in array_2
if any(digram in word for digram in array_1)]结果:
['lab', 'abc', 'foo', 'bar']您还可以使用filter
result_list = list(filter(lambda word:
any(digram in word for digram in array_1),
array_2)发布于 2021-03-23 05:18:34
我不知道有什么技巧可以让它更快,但我有一些小的改进可以提供。在这种情况下,使用numpy.arrays没有任何效果,因为您无论如何都是手动遍历单个条目。只有当有一些numpy方法可以帮助我们完成任务时,数组才能提供优势。目前,我建议在匹配后从list_2中删除条目,并使用while循环检查list_2是否仍有条目。
编辑
从一开始就使用set逻辑实际上似乎更快一点。我已经添加了这个方法。
以下是一些基本的速度比较和@Prune's的建议:
from time import time
def original(list_1, list_2, result_list):
for word_to_search in list_1:
for potential_word in list_2:
if word_to_search in potential_word:
result_list.append(potential_word)
return list(set(result_list))
def while_loop(list_1, list_2, result_list):
i = 0
while i < len(list_1) and list_2:
word_to_search = list_1[i]
for potential_word in list_2:
if word_to_search in potential_word:
result_list.append(potential_word)
list_2.remove(potential_word)
i += 1
return result_list
def set_(list_1, list_2, result_list):
result_set = set()
for word_to_search in list_1:
for potential_word in list_2:
if word_to_search in potential_word:
result_set.add(potential_word)
return list(result_set)
def any_(list_1, list_2, result_list):
return [
word for word in list_2 if any(digram in word for digram in list_1)
]
def filter_(list_1, list_2, result_list):
return list(
filter(lambda word: any(digram in word for digram in list_1), list_2)
)
methods = {
'original': original,
'while_loop': while_loop,
'any': any_,
'filter': filter_,
}
result_list = []
list_1 = ['ab', 'fo', 'ba']
list_2 = ['lab', 'abc', 'zwf', 'foo', 'bar']
for name, method in methods.items():
start = time()
for i in range(10000):
method(list_1, list_2, result_list)
stop = time()
print(f'{name}: {stop-start}')返回:
original: 1.475600004196167
while_loop: 0.006448030471801758
set: 0.004959821701049805
any: 0.006943941116333008
filter: 0.008928060531616211根据您的实际数据,这可能是完全关闭的。
编辑
我觉得可能会有一些很好的方法来使用list_2.__str__()和一些字符串方法,这将是非常快的,但我现在想不出一个。您也可以使用regex,但这样做可能会很慢。
https://stackoverflow.com/questions/66753680
复制相似问题