Python 从Numpy数据数组中提取给定行和列的最快方法是什么?

Python 从Numpy数据数组中提取给定行和列的最快方法是什么?,python,performance,optimization,numpy,scipy,Python,Performance,Optimization,Numpy,Scipy,我有一个大的(约14000 x 14000)方阵,表示为Numpyndarray。我希望提取大量的行和列——我预先知道这些行和列的索引,尽管实际上并非所有的行和列都为零——以得到一个新的平方矩阵(大约10000 x 10000) 我发现最快的方法是: > timeit A[np.ix_(indices, indices)] 1 loops, best of 3: 6.19 s per loop 但是,这比矩阵乘法所需的时间慢得多: > timeit np.multiply(A, A

我有一个大的(约14000 x 14000)方阵,表示为Numpy
ndarray
。我希望提取大量的行和列——我预先知道这些行和列的索引,尽管实际上并非所有的行和列都为零——以得到一个新的平方矩阵(大约10000 x 10000)

我发现最快的方法是:

> timeit A[np.ix_(indices, indices)]
1 loops, best of 3: 6.19 s per loop
但是,这比矩阵乘法所需的时间慢得多:

> timeit np.multiply(A, A)
1 loops, best of 3: 982 ms per loop
这似乎很奇怪,因为行/列提取和矩阵乘法都需要分配一个新数组(矩阵乘法的结果比提取的结果更大),但矩阵乘法还需要执行额外的计算


因此,问题是:是否有一种更有效的方法来执行提取,特别是至少与矩阵乘法一样快?

如果我尝试重现您的问题,我看不到如此剧烈的效果。我注意到,根据您选择的索引数量,索引甚至可以比乘法更快

>>> import numpy as np
>>> np.__version__
Out[1]: '1.9.0'
>>> N = 14000
>>> A = np.random.random(size=[N, N])

>>> indices = np.sort(np.random.choice(np.arange(N), 0.9*N, replace=False))
>>> timeit A[np.ix_(indices, indices)]
1 loops, best of 3: 1.02 s per loop
>>> timeit A.take(indices, axis=0).take(indices, axis=1)
1 loops, best of 3: 1.37 s per loop
>>> timeit np.multiply(A,A)
1 loops, best of 3: 748 ms per loop

>>> indices = np.sort(np.random.choice(np.arange(N), 0.7*N, replace=False))
>>> timeit A[np.ix_(indices, indices)]
1 loops, best of 3: 633 ms per loop
>>> timeit A.take(indices, axis=0).take(indices, axis=1)
1 loops, best of 3: 946 ms per loop
>>> timeit np.multiply(A,A)
1 loops, best of 3: 728 ms per loop

乘法(A,A)是元素乘法。使用
np.dot(A,A)
进行矩阵乘法。如果您提供了一个工作程序来处理随机数据,这会有所帮助。我曾经发现np.take()比用[]索引要快,但我不确定这对您的情况是否重要。无论如何试试看:@JohnZwinck:是的,类似于
r=A.take(索引,轴=0)。take(索引,轴=1)
比使用
[]
(使用numpy 1.8.2)进行索引更快。你想让我调试你的
np.ix\ucode>调用吗,因为新的numpy一开始就抱怨一些可能很有趣的事情?使用不同的numpy 1.9 beta版,调用
np.ix_uu
效果很好,所以我假设我们使用的版本中只存在一个bug。虽然切换到NumPy 1.9有所帮助,但它并没有给我们带来我们真正想要的性能提升。我们最终用Fortran实现了这一部分,并调用了。