2017-06-12 141 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

相關問題