numpy vectorized:检查数组中的字符串是否以另一个数组中的字符串结尾

2024-09-30 01:18:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个数组包含字符串。对于一个数组中的每个字符串,我要检查它是否以第二个数组中的字符串结尾。在

输入:

strings = ['val1', 'val2', 'val3']
ends = ['1', '2', 'al1']

期望输出:

^{pr2}$

由于val11和{}结尾,所以(0,0)和(0,2)都是真的。在

我有以下工作代码:

import numpy as np

strings = ['val1', 'val2', 'val3']
ends = ['1', '2', 'al1']

def buildFunction(ending):
    return lambda x: x.endswith(ending)

funcs = list(map(buildFunction, ends))

def end_function_vector(val):
    return np.vectorize(lambda f, x: f(x))(funcs, np.repeat(val, len(funcs)))

result = np.array(list(map(end_function_vector, strings)))

并返回所需的输出。在

但是,对于大型数组(~109输出元素),最后一行中的map需要相当长的时间,因为np.vectorize和{}几乎只是for循环的包装器。有人知道一种更快的矢量化方法吗?在


Tags: 字符串mapdef结尾endingnp数组funcs
2条回答

这是一个几乎*矢量化的方法,利用^{}-

# Get lengths of strings in each array
lens_strings = np.array(list(map(len,strings)))
lens_ends = np.array(list(map(len,ends)))

# Get the right most index of match, add the ends strings.
# The matching ones would cover the entire lengths of strings.
# So, do a final comparison against those lengths.
rfind = np.core.defchararray.rfind
out = rfind(strings[:,None], ends) + lens_ends == lens_strings[:,None]

样本运行-

^{pr2}$

*几乎是因为使用了map,但由于我们只使用它来获取输入元素的字符串长度,因此与解决我们的情况所需的其他操作相比,它的成本必须是最小的。在

Numpy对chararray有这样的操作:numpy.core.defchararray.endswith()。在

下面的代码可以大大加快速度,但是在创建两个与输出数组大小相同的数组时,确实需要大量内存:

A = np.array(['val1', 'val2', 'val3'])
B = np.array(['1', '2', 'al1'])

A_matrix = np.repeat(A[:, np.newaxis], len(B), axis=1)
B_matrix = np.repeat(B[:, np.newaxis], len(A), axis=1).transpose()

result = np.core.defchararray.endswith(A_matrix, B_matrix)

更新:
如Divakar所述,上述代码可合并为:

^{pr2}$

相关问题 更多 >

    热门问题