您可能考虑的另一种方法:
def iterative_numpy(a):
mask = a != 1
out = np.array([ a[i,mask[i]] for i xrange(a.shape[0]) ])
return out
Divakar的方法loop_compr_based计算沿着掩码行的总和以及该结果的累积和.这种方法避免了这种求和,但仍然必须迭代a的行.它还返回一个数组数组.这有一个烦恼,必须用语法out [1] [2]而不是out [1,2]索引.将时间与矩阵随机整数矩阵进行比较:
In [4]: a = np.random.random_integers(-1,1, size = (3,30))
In [5]: %timeit iterative_numpy(a)
100000 loops, best of 3: 11.1 us per loop
In [6]: %timeit loop_compr_based(a)
10000 loops, best of 3: 20.2 us per loop
In [7]: a = np.random.random_integers(-1,1, size = (30,3))
In [8]: %timeit iterative_numpy(a)
10000 loops, best of 3: 59.5 us per loop
In [9]: %timeit loop_compr_based(a)
10000 loops, best of 3: 30.8 us per loop
In [10]: a = np.random.random_integers(-1,1, size = (30,30))
In [11]: %timeit iterative_numpy(a)
10000 loops, best of 3: 64.6 us per loop
In [12]: %timeit loop_compr_based(a)
10000 loops, best of 3: 36 us per loop
当列数多于行数时,iterative_numpy将胜出.当行数多于列时,loop_compr_based获胜但转置第一个将提高两种方法的性能.当维度相对相同时,loop_compr_based最好.
重要的侧面讨论
在实现之外,重要的是要注意任何具有不均匀形状的numpy数组不是实际数组,因为值不占用连续的内存部分,而且通常的数组操作不能用作预期.
举个例子:
>>> a = np.array([[1,2,3],[1,2],[1]])
>>> a*2
array([[1, 2, 3, 1, 2, 3], [1, 2, 1, 2], [1, 1]], dtype=object)
请注意,numpy实际上告诉我们这不是通常的numpy数组,注释为dtype = object.
因此,最好只列出numpy数组并相应地使用它们.