我正在处理一个大阵列D
,我遇到了内存问题。但是,该大数组的条目实际上只是更小数组B
的元素的副本。现在我的想法是使用类似于"动态视图"进入B
而不是构建完整的D
。例如,是否可以使用函数D_fun
之类的数组来读取B
的正确元素?即
def D_fun(B, I, J):
i = convert_i_idx(I, J)
j = convert_j_idx(I, J)
return B[i,j]
然后我可以使用D_fun
做一些矩阵和向量乘法。
当然,其他任何可以让我将B
的元素重复复制到一个巨大的矩阵中的东西都会受到赞赏。
编辑:我意识到如果我在其他代码中投入一些时间,我可以将矩阵D
作为一个块矩阵,对角线上的B
s,否则为零。
答案 0 :(得分:3)
通常由subclassing numpy.ndarray完成并重载__getitem__, __setitem__, __delitem__
(通过[]
进行类似数组的访问)重新映射像D_fun(..)
这样的索引。不过,我不确定这是否可以与C中实现的numpy部分结合使用。
有些担忧:
当您通过小矩阵D
对大矩阵B
进行计算时,numpy可能会创建具有实际尺寸的D副本,因此使用的空间比想要的多。
如果多个(I1,J1), (I2,J2)..
映射到同一个(i,j)
,D[I1,J1] = newValue
也会将D(I2,J2)
设置为newValue
。
答案 1 :(得分:1)
np.dot
使用编译库来执行快速矩阵产品。这限制了数据类型(整数,浮点数),并要求数据是连续的。我建议研究最近关于大点产品的问题,numpy: efficient, large dot products
使用自定义__getitem__
定义类是一种使用索引语法访问对象的方法。在numpy/lib/index_tricks.py
中查找一些有趣的示例,np.mgrid
,np.r_
,np.s_
等。但这主要是语法增强。它并没有避免在D
和B
之间定义强大而有效的映射问题。
在尝试对子ndarray
进行子类化之前,请先了解np.matrix
或np.ma
的实现。 scipy.sparse
还会在很多方面创建类似ndarray
的行,但不会将ndarray
作为子类。
在D_fun
I
和J
标量中?如果是这样,这种转换将非常有效。如果它们可以是数组,列表或切片(B[atuple]
实现的任何东西)会更好,但这可能是很多工作。
def D_fun(B, I, J):
i = convert_i_idx(I, J)
j = convert_j_idx(I, J)
return B[i,j]
def __getitem__(self, atuple):
# sketch of a getitem version of your function
I, J = atuple
<select B based on I,J?>
i = convert_i_idx(I, J)
j = convert_j_idx(I, J)
return B.__getitem__((i,j))
从D
到B
的映射是什么样的?最简单,最有效的映射是D
只是B
的更高维度集合,即
D = np.array([B0,B1,B2,...,Bn])
D[0,...] == B0
D[n1:n2,....] == B0
,切片
但是,如果B0
值分散在D
左右,那么有效,可靠的映射几率非常小。