Numpy矩阵行比较

时间:2015-06-12 09:21:49

标签: python performance numpy matrix comparison

问题更侧重于计算的表现。

我有2个矩阵,列数相同,行数不同。一个矩阵是'模式',其行必须与其他矩阵行(所有行)分别进行比较,然后才能提取等于pattern,std,...的均值统计值。 所以,我有以下矩阵,计算如下:

numCols = 10
pattern = np.random.randint(0,2,size=(7,numCols))
matrix = np.random.randint(0,2,size=(5,numCols))

comp_mean = np.zeros(pattern.shape[0])
for i in range(pattern.shape[0]):
    comp_mean[i] = np.mean(np.sum(pattern[i,:] == matrix, axis=1))

print comp_mean # Output example: [ 1.6  1.   1.6  2.2  2.   2.   1.6]

这很清楚。问题是两者的矩阵行数都要大得多(~1.000.000)。所以这段代码变得很慢。我试图实现numpy syntaxis,因为有时候我会惊讶于改善计算时间。所以我做了以下代码(它可能很奇怪,但它有效!):

comp_mean = np.mean( np.sum( (pattern[np.repeat(np.arange(pattern.shape[0]), matrix.shape[0])].ravel() == np.tile(matrix.ravel(),pattern.shape[0])).reshape(pattern.shape[0],matrix.shape[0],matrix.shape[1]), axis=2 ),axis=1)
print comp_mean

但是,此代码比使用'for'bucle的前一代码慢。所以我想知道是否有可能加快计算速度。

修改

我已经检查了真实矩阵的不同方法的运行时间,结果如下:

  • 我 - 方法1: 18.04
  • 我 - 方法2: 303.10
  • Divakar - 方法1: 18.79
  • Divakar - 方法2: 65.11
  • Divakar - 方法3.1: 137.78
  • Divakar - 方法3.2: 59.59
  • Divakar - 方法4: 6.06

修改(2)

以前在笔记本电脑中执行的运行。我已在桌面上运行代码。我避免了最糟糕的结果,现在新的运行时间不同了:

  • 我 - 方法1: 6.25
  • Divakar - 方法1: 4.01
  • Divakar - 方法2: 3.66
  • Divakar - 方法4: 3.12

2 个答案:

答案 0 :(得分:3)

这里可以建议使用broadcasting的几种方法。

方法#1

out = np.mean(np.sum(pattern[:,None,:] == matrix[None,:,:],2),1)

方法#2

mrows = matrix.shape[0]
prows = pattern.shape[0]
out = (pattern[:,None,:] == matrix[None,:,:]).reshape(prows,-1).sum(1)/mrows

方法#3

mrows = matrix.shape[0]
prows = pattern.shape[0]
out = np.einsum('ijk->i',(pattern[:,None,:] == matrix[None,:,:]).astype(int))/mrows
# OR out = np.einsum('ijk->i',(pattern[:,None,:] == matrix[None,:,:])+0)/mrows

方法#4

如果matrix中的行数是一个很大的数字,那么坚持使用for循环以避免这种情况下的巨大内存需求可能会更好,这可能也会导致运行时间变慢。相反,我们可以在每个循环迭代中进行一些优化。这是一个可能的优化显示 -

mrows = matrix.shape[0]
comp_mean = np.zeros(pattern.shape[0])
for i in range(pattern.shape[0]):
    comp_mean[i] = (pattern[i,:] == matrix).sum()
comp_mean = comp_mean/mrows

答案 1 :(得分:0)

你可以尝试一下这个:

import scipy.ndimage.measurements

comp_mean = np.zeros(pattern.shape[0])
for i in range(pattern.shape[0]):
    m = scipy.ndimage.measurements.histogram(matrix,0,1,2,pattern[i],[0,1])
    comp_mean[i] = m[0][0]+m[1][1]
comp_mean /= matrix.shape[0]

问候。