Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 加速Numpy阵列切片_Python_Numpy - Fatal编程技术网

Python 加速Numpy阵列切片

Python 加速Numpy阵列切片,python,numpy,Python,Numpy,我需要沿二维切片一个中等大小的2d Numpy数组。例如, import numpy as np X = np.random.normal(loc=0, scale=1, size=(3000, 100)) 从这个数组中,我需要选择大量的行和少量的列,例如 row_idx = np.random.random_integers(0, 2999, 2500) col_idx = np.random.random_integers(0, 99, 10) 现在,我通过以下命令执行此操作: X.ta

我需要沿二维切片一个中等大小的2d Numpy数组。例如,

import numpy as np
X = np.random.normal(loc=0, scale=1, size=(3000, 100))
从这个数组中,我需要选择大量的行和少量的列,例如

row_idx = np.random.random_integers(0, 2999, 2500)
col_idx = np.random.random_integers(0, 99, 10)
现在,我通过以下命令执行此操作:

X.take(col_idx, axis=1).take(row_idx, axis=0)
这在我的计算机上大约需要115µs。问题是每次运行我都需要执行数百万次此步骤

你有没有看到加快速度的机会

编辑(附加信息): 我有一个矩阵X,它是nxk。n行包含1xk向量。 有三个集合:活动集合(V)、左侧集合(L)和右侧集合(R)。此外,还有系数v0和v。我需要计算这个数量:(对不起,我不能发布图片)。问题中的公式选择左(右)集中X的所有行以及活动集中的所有列

编辑2

我发现了另一个小小的进步

X.take(col_idx, axis=1, mode='clip').take(row_idx, axis=0, mode='clip')

稍微快一点(在我的机器上大约是25%)。

您可以使用二维索引:

X[row_idx,col_idx[:,None]]
但在我的机器上需要1毫秒,而使用你的方法需要300秒


看起来你的方法是你能做的最好的了,除非你有关于
行idx
列idx

中的值的额外信息,让我们做一些事情,制作一个1D索引数组,满足n维网格的条件

def make_multi_index(arr, *inds):
    tmp = np.meshgrid(*inds, indexing='ij')
    idx = np.vstack([x.ravel() for x in tmp])
    return np.ravel_multi_index(idx, X.shape)
使用测试阵列和原始案例作为参考:

%timeit X.take(col_idx, axis=1).take(row_idx, axis=0)
10000 loops, best of 3: 95.4 µs per loop
让我们使用此函数构建索引,保存索引,然后使用take返回所需的输出:

inds = make_multi_index(X, row_idx, col_idx)
tmp = np.take(X,inds).reshape(row_idx.shape[0], col_idx.shape[0])

np.allclose(tmp, X.take(col_idx, axis=1).take(row_idx, axis=0))
Out[128]: True
因此,建立我们的指数并保持它们似乎是可行的,现在就时间而言:

%timeit make_multi_index(X, row_idx, col_idx)
1000 loops, best of 3: 356 µs per loop

%timeit np.take(X,inds).reshape(row_idx.shape[0], col_idx.shape[0])
10000 loops, best of 3: 59.9 µs per loop

所以,当它发生的时候,并不是非常好——这可能会随着你想要从中获得更多维度而变得更好。无论如何,如果您将这些索引保留超过10-15次迭代,或者如果您添加一个额外维度并同时获取所有非活动数据集,则可能会有所帮助。

使用
take()
方法将需要复制选定的行和列。你应该考虑一下你的算法,让它变得不必要。如果没有进一步的上下文,我们无法告诉您如何做。您的索引多久更改一次?行索引在几十次观察中保持不变(更准确地说:我有k个变量,它们被分为活动集和非活动集,我需要检查非活动集中的哪个变量最适合——也就是说,只要我检查非活动集中的变量,行索引就保持不变)这听起来很有希望。我想如果我能利用这种方法,也许有某种方法可以减少索引更改的数量。谢谢!