将具有坐标和值的字典转换为2D数组

时间:2020-11-06 08:03:37

标签: python numpy

假设给出下一个字典:

list_t = ['1.234', '3.6654', '7.134123', '2.2323', 'Someone']
for i in range(len (list_t) - 1):
    list_t [i] = round (float (list_t [i]), 2)
print (list_t)

在每个键上方的字典中,每个键在矩阵{(0, 0): 1, (1, 1): 12, (2, 2): 802, (3, 3): 1687, (4, 4): 11, (5, 4): 4, (6, 5): 593, (7, 4): 4} 中显示一个点,一个值显示在矩阵中找到的值。我该如何构造一个数组,该数组包含位于每个点(x, y)x上的值?

根据字典上方的预期结果是:

y

9 个答案:

答案 0 :(得分:2)

您可以使用np.add.at,通过键预先定义数组的形状:

d = {(0, 0): 1, (1, 1): 12, (2, 2): 802, (3, 3): 1687, (4, 4): 11, 
     (5, 4): 4, (6, 5): 593, (7, 4): 4}

i,j = zip(*d.keys())
a = np.zeros((max(i)+1,max(j)+1), np.int32)
np.add.at(a, tuple((i,j)), tuple(d.values()))

a
array([[   1,    0,    0,    0,    0,    0],
       [   0,   12,    0,    0,    0,    0],
       [   0,    0,  802,    0,    0,    0],
       [   0,    0,    0, 1687,    0,    0],
       [   0,    0,    0,    0,   11,    0],
       [   0,    0,    0,    0,    4,    0],
       [   0,    0,    0,    0,    0,  593],
       [   0,    0,    0,    0,    4,    0]])

答案 1 :(得分:1)

使用coo稀疏矩阵,然后转换为数组:

from scipy.sparse import coo_matrix

data= {(0, 0): 1, (1, 1): 12, (2, 2): 802, (3, 3): 1687, (4, 4): 11, (5, 4): 4, (6, 5): 593, (7, 4): 4}

row, col, fill = zip(*[(*k, v) for k, v in data.items()])

result = coo_matrix((fill, (row, col)), shape=(8, 6)).toarray()
print(result)

输出

[[   1    0    0    0    0    0]
 [   0   12    0    0    0    0]
 [   0    0  802    0    0    0]
 [   0    0    0 1687    0    0]
 [   0    0    0    0   11    0]
 [   0    0    0    0    4    0]
 [   0    0    0    0    0  593]
 [   0    0    0    0    4    0]]

答案 2 :(得分:1)

我的2美分:

n=np.zeros([max(d.keys(), key=lambda x:x[0])[0]+1,max(d.keys(), key=lambda x:x[1])[1]+1], int)

for i,k in d.items():
    n[i[0], i[1]]=k

>>>print(n)

array([[   1,    0,    0,    0,    0,    0],
       [   0,   12,    0,    0,    0,    0],
       [   0,    0,  802,    0,    0,    0],
       [   0,    0,    0, 1687,    0,    0],
       [   0,    0,    0,    0,   11,    0],
       [   0,    0,    0,    0,    4,    0],
       [   0,    0,    0,    0,    0,  593],
       [   0,    0,    0,    0,    4,    0]])

答案 3 :(得分:1)

那只是稀疏矩阵的键(dok)表示形式的字典。这样。 。

from scipy.sparse import dok_matrix

out = dok_matrix((8, 8), dtype = int)
out._update(d)
out.todense()

Out[]: 
matrix([[   1,    0,    0,    0,    0,    0,    0,    0],
        [   0,   12,    0,    0,    0,    0,    0,    0],
        [   0,    0,  802,    0,    0,    0,    0,    0],
        [   0,    0,    0, 1687,    0,    0,    0,    0],
        [   0,    0,    0,    0,   11,    0,    0,    0],
        [   0,    0,    0,    0,    4,    0,    0,    0],
        [   0,    0,    0,    0,    0,  593,    0,    0],
        [   0,    0,    0,    0,    4,    0,    0,    0]])

答案 4 :(得分:1)

提取纯numpy中任何可迭代值的最有效方法是np.fromiter。这是使用它的好时机:

方法1

d = {(0, 0): 1, (1, 1): 12, (2, 2): 802, (3, 3): 1687, (4, 4): 11, (5, 4): 4, (6, 5): 593, (7, 4): 4}
X = np.zeros((8,8), dtype=int)
idx = np.fromiter(d, dtype='i,i').view(int).reshape(-1, 2)
vals = np.fromiter(d.values(), dtype=float)
X[idx[:,0], idx[:,1]] = vals

备注:我的意思是提取对应于某种形状的iterable值。否则,还需要itertools.chain

方法2

itertools.chain是扁平化可迭代对象的非常快速的方法,它极大地促进了np.fromiter的发展。它对可重复项的大小没有要求。比以前的替代方法快2.5倍:

import itertools
X = np.zeros((8,8), dtype=int)
idx = np.fromiter(itertools.chain(*d.keys()), dtype=int).reshape(-1,2)
vals = np.fromiter(d.values(), dtype=float)
X[idx[:,0], idx[:,1]] = vals

方法3

zip可以代替itertools.chain使用,但比方法2慢(5-10%)。

X = np.zeros((8,8), dtype=int)
idx1, idx2 = zip(*d.keys())
vals = np.fromiter(d.values(), dtype=float)
X[idx1, idx2] = vals

答案 5 :(得分:0)

如果已经知道数组大小,则可以执行此操作,

import numpy as np

arr = np.zeros((8, 6), dtype='int')
d = {(0, 0): 1, (1, 1): 12, (2, 2): 802, (3, 3): 1687, (4, 4): 11, (5, 4): 4, (6, 5): 593, (7, 4): 4}

for key, val in d.items():
    arr[key[0]][key[1]] = val
    
array([[   1,    0,    0,    0,    0,    0],
   [   0,   12,    0,    0,    0,    0],
   [   0,    0,  802,    0,    0,    0],
   [   0,    0,    0, 1687,    0,    0],
   [   0,    0,    0,    0,   11,    0],
   [   0,    0,    0,    0,    4,    0],
   [   0,    0,    0,    0,    0,  593],
   [   0,    0,    0,    0,    4,    0]])

答案 6 :(得分:0)

    import numpy as np

    cols = max(key[0] for key in d) + 1
    rows = max(key[1] for key in d) + 1

    mat = np.zeros((cols, rows), dtype=np.int)
    for point in d: mat[point] = d[point]

    print(mat)

####### result #######
[[   1    0    0    0    0    0]
 [   0   12    0    0    0    0]
 [   0    0  802    0    0    0]
 [   0    0    0 1687    0    0]
 [   0    0    0    0   11    0]
 [   0    0    0    0    4    0]
 [   0    0    0    0    0  593]
 [   0    0    0    0    4    0]]

答案 7 :(得分:0)

另一个解决方案是:

import numpy as np

d = {(0, 0): 1, (1, 1): 12, (2, 2): 802, (3, 3): 1687, (4, 4): 11, (5, 4): 4, (6, 5): 593, (7, 4): 4}

X = np.zeros((8,8))
X[tuple(np.array(list(d.keys())).T)] = list(d.values())

哪个输出:

array([[   1,    0,    0,    0,    0,    0,    0,    0],
       [   0,   12,    0,    0,    0,    0,    0,    0],
       [   0,    0,  802,    0,    0,    0,    0,    0],
       [   0,    0,    0, 1687,    0,    0,    0,    0],
       [   0,    0,    0,    0,   11,    0,    0,    0],
       [   0,    0,    0,    0,    4,    0,    0,    0],
       [   0,    0,    0,    0,    0,  593,    0,    0],
       [   0,    0,    0,    0,    4,    0,    0,    0]], dtype=uint32)

使用numpy数组的元组,可以将其直接传递到矩阵以获取元素,然后分配字典的值。

答案 8 :(得分:0)

尝试一下

time %% 15

如果您的矩阵是其他大小,请考虑更改零初始化

输出

import numpy as np
matrix = np.zeros((8,6))
your_dict = {(0, 0): 1, (1, 1): 12, (2, 2): 802, (3, 3): 1687, (4, 4): 11, (5,4): 4, (6, 5): 593, (7, 4): 4}
for key, value in your_dict.items():
    matrix[key[0],key[1]] = value