Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.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_Arrays_Numpy - Fatal编程技术网

Python 不同大小数组的Numpy高效索引

Python 不同大小数组的Numpy高效索引,python,arrays,numpy,Python,Arrays,Numpy,看看这段代码: import numpy as np a = np.random.random(10) indicies = [ np.array([1, 4, 3]), np.array([2, 5, 8, 7, 3]), np.array([1, 2]), np.array([3, 2, 1]) ] result = np.zeros(2) result[0] = a[indicies[0]].sum() result[1] = a[indicies[2

看看这段代码:

import numpy as np

a = np.random.random(10)

indicies = [
    np.array([1, 4, 3]),
    np.array([2, 5, 8, 7, 3]),
    np.array([1, 2]),
    np.array([3, 2, 1])
]

result = np.zeros(2)
result[0] = a[indicies[0]].sum()
result[1] = a[indicies[2]].sum()
有没有办法更有效地获得
结果
?在我的例子中,
a
是一个非常大的数组


换句话说,我想从具有多个不同大小索引数组的
a
中选择元素,然后在一次操作中对它们求和,产生一个数组。

如果数组a非常大,则在循环时,如果索引数组包含多个索引数组,则可能会出现内存问题

要避免此问题,请使用迭代器而不是列表:

indices = iter(indices)

然后循环遍历迭代器。

使用
a
标记列表:

In [280]: [a[i].sum() for i in indicies]
Out[280]: 
[1.3986792680307709,
 2.6354365193743732,
 0.83324677494990895,
 1.8195179021311731]
当然可以将其包装在
np.array()

对于
标记的子集
项目,使用:

In [281]: [a[indicies[i]].sum() for i in [0,2]]
Out[281]: [1.3986792680307709, 0.83324677494990895]
一条评论指出,
标记
来自邻接矩阵,可能是稀疏的

我可以通过以下方式重新创建这样的阵列:

In [289]: A=np.zeros((4,10),int)
In [290]: for i in range(4): A[i,indicies[i]]=1
In [291]: A
Out[291]: 
array([[0, 1, 0, 1, 1, 0, 0, 0, 0, 0],
       [0, 0, 1, 1, 0, 1, 0, 1, 1, 0],
       [0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
       [0, 1, 1, 1, 0, 0, 0, 0, 0, 0]])
并使用矩阵积(
np.dot
)进行选择和求和:

In [292]: A.dot(a)
Out[292]: array([ 1.39867927,  2.63543652,  0.83324677,  1.8195179 ])
A[[0,2],:]。点(A)
将使用行的子集

稀疏矩阵版本具有行索引列表:

In [294]: Al=sparse.lil_matrix(A)
In [295]: Al.rows
Out[295]: array([[1, 3, 4], [2, 3, 5, 7, 8], [1, 2], [1, 2, 3]], dtype=object)
和一个矩阵积,它给出了相同的数字:

In [296]: Al*a
Out[296]: array([ 1.39867927,  2.63543652,  0.83324677,  1.8195179 ])

那么,对已经加载到RAM中的对象调用
iter
将如何帮助减少内存消耗呢?此外,如果您只是对索引中的某些内容执行
,Python将隐式地为您执行iter(索引)
。索引的来源是什么?对于您的问题,可能有一些非常优雅的解决方案,它们是二进制邻接矩阵的非零元素(行或列,因为矩阵是对称的,所以不重要)。还有另一种解决方案,如果邻接矩阵是
A
,可以这样写:
(A[[0,2][:,无]*A[[0,2],:])。sum(axis=1)
,但我不确定这是否更有效。如果用稀疏矩阵替换
A
,那么它甚至不起作用。换句话说,对于节点子集(在示例[0,2]),对其所有相邻节点的数组
a
中的值求和)Scipy sparse执行类似于矩阵乘法的行求和。因此,
A.dot(A)
可能是工作结果[1]和索引[2]-1和2的组合正确吗?为了清楚起见,这意味着我想要两个索引数组的结果,它们恰好是第0和第2个,所以将它们放在结果数组的位置0和1。可能是任何人。这只是一个随机的例子。我确实也想到了
a[[0,2],:].dot(a)
,但我认为这不太好,因为
a
矩阵是
NxN
并且
N
很大。然后我试着用稀疏矩阵来做,但没能让它工作。现在我意识到,
*
实际上是稀疏矩阵的点积,它与2D密集阵列不同,而2D密集阵列实际上是一个正态乘法。奇怪的因此,执行
A1[[0,2],:]*a
是可行的。在MATLAB中
*
是矩阵乘法,而
*
是元素乘法。稀疏矩阵是在复制MATLAB的
np.matrix
上建模的。较新的python添加了
@
以供矩阵乘法使用。显然
*
重载为类型
np.matrix
的矩阵乘法和类型
np.array
的元素乘法。应该知道:)