2017-06-12 101 views
2

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

输入:

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

希望的输出:

[[ True, False, True], 
[False, True, False], 
[False, False, False]] 

val1如在1以及在al1结束时,两个(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))) 

,并返回所需的输出。

然而,对于大阵列(〜10 9 输出元素)中的最后一行的map花费相当长的一段,因为np.vectorizemap是几乎围绕只是一个包装一个for循环。有谁知道更快,矢量化的方法来做到这一点?

回答

2

Numpy具有以下类型的操作: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指出,上面的代码可以整合到:

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

np.core.defchararray.endswith(A[:,None], B) 
+1

认为你可以简单地做:'np.core.defchararray.endswith(A [:,无],B)',我们有一个赢家! – Divakar

+0

很好的实施!它的工作速度比OP的基础快4到5倍。 –

1

这里是一个几乎*量化方法利用的NumPy broadcasting -

# 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] 

采样运行 -

In [224]: strings = np.array(['val1', 'val2', 'val3', 'val1y', 'val341']) 
    ...: ends = np.array(['1', '2', 'al1', 'l2']) 
    ...: 

In [225]: out 
Out[225]: 
array([[ True, False, True, False], 
     [False, True, False, True], 
     [False, False, False, False], 
     [False, False, False, False], 
     [ True, False, False, False]], dtype=bool) 

*几乎使用map因,但因为我们只用它来获取输入元素的字符串的长度,它的成本必须控制在最小限度与解决我们案件所需的其他行动相比。

+0

不错,但它占用了工作内存空间的两倍。 –

+0

但是“矢量化”实际上是否给出了并行计算? –

+0

@AndrewJaffe我认为OP意味着矢量化。并行将意味着留在Python中,但使用并行体系结构。这个问题看起来不像。 – Divakar

相关问题