使用类似numpy数组的函数

时间:2017-02-03 10:59:56

标签: python arrays numpy

我正在处理一个大阵列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,否则为零。

2 个答案:

答案 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.mgridnp.r_np.s_等。但这主要是语法增强。它并没有避免在DB之间定义强大而有效的映射问题。

在尝试对子ndarray进行子类化之前,请先了解np.matrixnp.ma的实现。 scipy.sparse还会在很多方面创建类似ndarray的行,但不会将ndarray作为子类。

D_fun IJ标量中?如果是这样,这种转换将非常有效。如果它们可以是数组,列表或切片(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))

DB的映射是什么样的?最简单,最有效的映射是D只是B的更高维度集合,即

 D = np.array([B0,B1,B2,...,Bn])
 D[0,...] == B0  

D[n1:n2,....] == B0,切片

的情况稍微复杂一些

但是,如果B0值分散在D左右,那么有效,可靠的映射几率非常小。