2D数组表示一个大型python dict,类似坐标的解决方案以节省内存

2D数组表示一个大型python dict,类似坐标的解决方案以节省内存,python,numpy,sparse-matrix,numba,Python,Numpy,Sparse Matrix,Numba,我尝试使用数组中的数据更新带有元组键的dict\u: myarray = np.array([[0, 0], # 0, 1 [0, 1], [1, 1], # 1, 2 [1, 2], # 1, 3 [2, 2], [1, 3]] ) # a lot of this with shape~(1

我尝试使用数组中的数据更新带有元组键的dict\u:

myarray = np.array([[0, 0],  # 0, 1
                    [0, 1],
                    [1, 1],  # 1, 2
                    [1, 2],  # 1, 3
                    [2, 2],
                    [1, 3]]
) # a lot of this with shape~(10e6, 2)

dict_with_tuples_key = {(0, 1): 1,
                        (3, 7): 1} # ~10e6 keys 
使用数组存储dict值(由于@MSeifert),我们得到以下结果:

def convert_dict_to_darray(dict_with_tuples_key, myarray):
    idx_max_array = np.max(myarray, axis=0)
    idx_max_dict  = np.max(dict_with_tuples_key.keys(), axis=0)
    lens = np.max([list(idx_max_array), list(idx_max_dict)], axis=0)
    xlen, ylen = lens[0] + 1, lens[1] + 1
    darray = np.zeros((xlen, ylen)) # Empty array to hold all indexes in myarray
    for key, value in dict_with_tuples_key.items():
        darray[key] = value
    return darray

@njit
def update_darray(darray, myarray):
    elements = myarray.shape[0]
    for i in range(elements):
        darray[myarray[i][0]][myarray[i][1]] += 1
    return darray

def darray_to_dict(darray):
    updated_dict = {}
    keys = zip(*map(list, np.nonzero(darray)))
    for x, y in keys:
        updated_dict[(x, y)] = darray[x, y]
    return updated_dict

darray = convert_dict_to_darray(dict_with_tuples_key, myarray)
darray = update_darray(darray, myarray)
我得到了所需的确切结果:

# print darray_to_dict(darray)
# {(0, 1): 2.0,
#  (0, 0): 1.0,
#  (1, 1): 1.0,
#  (2, 2): 1.0,
#  (1, 2): 1.0,
#  (1, 3): 1.0,
#  (3, 7): 1.0, }
对于小矩阵,它工作得很好,@njit工作得很快, 但是


创建巨大的空
darray=np.zero((xlen,ylen))
不适用于内存。我们如何避免分配一个非常稀疏的数组,而只存储非空值,如坐标格式的稀疏矩阵?

使用
scipy
中的
dok_矩阵
;一个
dock_矩阵
是一个基于稀疏矩阵的键字典。它们允许您以增量方式构建稀疏矩阵,并且不会分配不适合计算机内存的大量空
darray=np.zero((xlen,ylen))

要做的唯一更改是从scipy导入正确的模块,并在函数
convert\u dict\u to\u darray
中更改
darray
的定义

它将如下所示:

from scipy.sparse import dok_matrix

def convert_dict_to_darray(dict_with_tuples_key, myarray):
    idx_max_array = np.max(myarray, axis=0)
    idx_max_dict  = np.max(dict_with_tuples_key.keys(), axis=0)
    lens = np.max([list(idx_max_array), list(idx_max_dict)], axis=0)
    xlen, ylen = lens[0] + 1, lens[1] + 1
    darray = dok_matrix( (xlen, ylen) )
    for key, value in dict_with_tuples_key.items():
        darray[key[0], key[1]] = value
    return darray

您能否指定
xlen
ylen
有多大?也可能dict和np.ndarray都不是此任务的理想容器。你考虑过吗?但这取决于你想对数据做什么。我来自pandas,据我所知,pandas没有坐标存储,pandas存储在int64 numpy数组中。一旦我把它放在内存中,我就必须让它平行。如果我们能“猜”出darray矩阵的非零个数,我们就很接近了。矩阵是大的np.Zero([int(200e3),int(150e3)],但非常稀疏,可能有20e6个非零值。如果
key
已经是两个元素的
tuple
,那么做
darray[key[0],key[1]
只是一种解包和重新打包相同
tuple
的愚蠢方式;可以做
darray[key]
@ShadowRanger,你是对的。如果OP喜欢这个建议,我会让他这么做。我想建议对他已经做过的事情做出最小可能的改变。