python - 二维数组代表一个巨大的 python 字典,COOrdinate 类似解决方案以节省内存

标签 python numpy sparse-matrix numba

我尝试用数组中的数据更新 dict_with_tuples_key:

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 

使用数组存储字典值,(感谢@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.zeros((xlen, ylen)) 不适合内存。我们如何避免分配一个非常稀疏的数组,并且只存储非空值,如稀疏矩阵,COOrdinate 格式?

最佳答案

使用 scipy 中的 dok_matrixdock_matrix 是基于键的字典稀疏矩阵。它们允许您逐步构建稀疏矩阵,并且不会分配不适合您的计算机内存的巨大空 darray = np.zeros((xlen, ylen))

唯一要做的更改是从 scipy 导入正确的模块,并更改函数 convert_dict_to_darraydarray 的定义。

它看起来像这样:

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

关于python - 二维数组代表一个巨大的 python 字典,COOrdinate 类似解决方案以节省内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35340440/

相关文章:

python - 将稀疏矩阵转储到文件中

python - Django 映射到 Postgres citext 数组返回一个 str 而不是一个列表

python - 准备张量分配时出现意外失败 : tensorflow/lite/kernels/reshape. cc :85 num_input_elements ! = num_output_elements (1200 != 0)

matlab - 稀疏矩阵的非零元素

python - 当列表中有两个连续相似的数字时,如何打破循环?

python - Python 中 Pandas 的快速取子集

python - 卡住 OS X 上的 pip 要求、NumPy 和 SciPy

python - numpy 将 2D 矩阵 reshape 为对称矩阵数组(3D 数组),无需循环

python - 标准化 Scipy 稀疏矩阵的有效方法

matrix - 计算符号二进制矩阵的共轭或逆的单个元素