嵌套的循环Numpy数组:是否可以进行矢量化?

时间:2015-04-24 02:47:30

标签: python numpy

我一直试图加快下面的代码查找索引,这将从列表中获取一个字符串" name",最后计算它在两个数据部分中的精确匹配数。

这个过程非常缓慢。我读到了在使用numpy数组时替换for循环,但不知道如何使用正则表达式匹配来处理/接近创建矢量化版本。

x = np.empty([38000, 8000])  
y = np.empty([38000, 8000])  
for i in range(0, 38000):
    for j in range(0, 8000):
        x[i, j] = len(re.findall('\\b'+name[index[j]]+'\\b', data[i][1]))
        y[i, j] = len(re.findall('\\b'+name[index[j]]+'\\b', data[i][2]))

非常感谢任何见解,

2 个答案:

答案 0 :(得分:1)

矢量化不会对你有所帮助,但避免重复工作:

patterns = [re.compile('\\b'+name[idx]+'\\b') for idx in index]
for i, row in enumerate(data):
    for j, patt in enumerate(patterns):
        x[i, j] = len(patt.findall(row[1]))
        y[i, j] = len(patt.findall(row[2]))

答案 1 :(得分:1)

矢量化函数......

首先定义一个函数并对其进行矢量化:

def count_words(word, sentence):
    return len(re.findall(r'\b%s\b'%word, sentence))

vcount_words = np.vectorize(count_words)

然后应用(这里的字是数组800元素数组,数据是3800X2矩阵)

vcount_words(names, data[:,:1])

更小的例子,所以它适合这里(5X3):

names = ['aaa', 'bbb', 'ccc']
data = np.array([['aaa aaa aaa bbb dd', 'ee ff ccc ee ee dd bbb ee'],
                 ['aaa ccc dd aaa ff ff ee', 'dd ccc ee ccc dd ee ff'],
                 ['ee aaa ff ccc ff ee aaa dd bbb', 'aaa'],
                 ['ff ee ccc ccc', 'dd'],
                 ['ccc ee aaa dd', 'ccc bbb ee aaa bbb ff ee']])
x = vcount_words(names, data[:,:1])
# returns >>>
array([[3, 1, 0],
       [2, 0, 1],
       [2, 1, 1],
       [0, 0, 2],
       [1, 0, 1]])

根据您的数据进行相应调整。这可以通过不重新编译函数中的正则表达式来加速(预编译和索引到它)。每当你用for循环遍历numpy数组时,我也会调查numba。

但是,这表明矢量化是一种函数方法,你已经“接受”并且它已经晚了。