将具有已知索引的字典转换为多维数组

时间:2016-08-02 20:30:08

标签: python numpy dictionary

我有一个字典,其条目标记为{(k,i): value, ...}。我现在想将此字典转换为二维数组,其中位置[k,i]处的数组元素的值是带有标签(k,i)的字典中的值。行的长度不一定具有相同的大小(例如,行k = 4可以上升到索引i = 60,而行k = 24可以上升到索引i = 31)。由于不对称性,可以使特定行中的所有附加条目等于0以便具有矩形矩阵。

2 个答案:

答案 0 :(得分:3)

这是一种方法 -

# Get keys (as indices for output) and values as arrays
idx = np.array(d.keys())
vals = np.array(d.values())

# Get dimensions of output array based on max extents of indices
dims = idx.max(0)+1

# Setup output array and assign values into it indexed by those indices
out = np.zeros(dims,dtype=vals.dtype)
out[idx[:,0],idx[:,1]] = vals

我们也可以使用稀疏矩阵来获得最终输出。例如与coordinate format sparse matrices。当作为稀疏矩阵保存时,这将是内存有效的。所以,最后一步可以用这样的东西代替 -

from scipy.sparse import coo_matrix

out = coo_matrix((vals, (idx[:,0], idx[:,1])), dims).toarray()

示例运行 -

In [70]: d
Out[70]: {(1, 4): 120, (2, 2): 72, (2, 3): 100, (5, 2): 88}

In [71]: out
Out[71]: 
array([[  0,   0,   0,   0,   0],
       [  0,   0,   0,   0, 120],
       [  0,   0,  72, 100,   0],
       [  0,   0,   0,   0,   0],
       [  0,   0,   0,   0,   0],
       [  0,   0,  88,   0,   0]])

为了使它对任意数量维的ndarray都是通用的,我们可以使用线性索引并使用np.put将值赋给输出数组。因此,在我们的第一种方法中,只需用这样的方法替换分配值的最后一步 -

np.put(out,np.ravel_multi_index(idx.T,dims),vals)

示例运行 -

In [106]: d
Out[106]: {(1,0,0): 99, (1,0,4): 120, (2,0,2): 72, (2,1,3): 100, (3,0,2): 88}

In [107]: out
Out[107]: 
array([[[  0,   0,   0,   0,   0],
        [  0,   0,   0,   0,   0]],

       [[ 99,   0,   0,   0, 120],
        [  0,   0,   0,   0,   0]],

       [[  0,   0,  72,   0,   0],
        [  0,   0,   0, 100,   0]],

       [[  0,   0,  88,   0,   0],
        [  0,   0,   0,   0,   0]]])

答案 1 :(得分:0)

有一个字典键稀疏格式,可以从这样的字典构建。

Divakar's d示例开始:

In [1189]: d={(1, 4): 120, (2, 2): 72, (2, 3): 100, (5, 2): 88}

制作一个正确形状的空稀疏矩阵并且dtype:

In [1190]: M=sparse.dok_matrix((6,5),dtype=int)
In [1191]: M
Out[1191]: 
<6x5 sparse matrix of type '<class 'numpy.int32'>'
    with 0 stored elements in Dictionary Of Keys format>

通过字典d添加update值。这是有效的,因为这种特殊的稀疏格式是dict子类。虽然没有记录这个技巧(至少不是我知道的),但是要知道了:

In [1192]: M.update(d)
In [1193]: M
Out[1193]: 
<6x5 sparse matrix of type '<class 'numpy.int32'>'
    with 4 stored elements in Dictionary Of Keys format>
In [1194]: M.A    # convert M to numpy array (handy display trick)
Out[1194]: 
array([[  0,   0,   0,   0,   0],
       [  0,   0,   0,   0, 120],
       [  0,   0,  72, 100,   0],
       [  0,   0,   0,   0,   0],
       [  0,   0,   0,   0,   0],
       [  0,   0,  88,   0,   0]])

M可以转换为其他稀疏格式coocsr。实际上sparse本身会进行这种转换,具体取决于用途(显示,计算等)。

In [1196]: print(M)
  (2, 3)    100
  (5, 2)    88
  (1, 4)    120
  (2, 2)    72