如何将具有坐标和频率的字典转换为矩阵?

时间:2019-08-14 11:48:10

标签: python pandas numpy dictionary plot

我有一本字典,看起来像:

data = {(-1.0, 4.0): 1, (2.0, 2.0): 12, (3.0, 1.0): 8}

我想制作一个看起来像这样的矩阵:

[[0. 0. 0. 0. 0.]
 [1. 0. 0. 0. 0.]
 [0. 0. 0. 12. 0.]
 [0. 0. 0. 0. 8.]
 [0. 0. 0. 0. 0.]]

其中字典中的每个键在我的矩阵中都是“坐标”(从左下角开始),并且轴的界限由我定义(xlim:-3、13,ylim:-6、8) em>未显示。

我尝试通过以下方式尝试此操作:

matrix = np.zeros((5,5))
for (x, y), z in data.items():
    x = int(x)
    y = int(y)

    matrix[y,x] = z

但是我在使用负尺寸时遇到了错误。

我的最终目标是将字典绘制为某种直方图,其中坐标为x,y,字典值(频率)为z维度或“深度”。

3 个答案:

答案 0 :(得分:1)

类似于已经提出的建议,将矩阵“移动”到正区域,然后使用x和y偏移量定位坐标:

import numpy as np
data = {(-1.0, 4.0): 1, (2.0, 2.0): 12, (3.0, 1.0): 8}
x_offset = 3
y_offset = 6
mat = np.zeros((17, 15))
for (x, y), z in data.items():
    mat[int(y + y_offset), int(x + x_offset)] = z

修改

好吧,我想这就是您的想法(我假设x和y坐标中都存在负值):

如果您要对x和y值的范围进行硬编码(xlim:-3、13,ylim:-6、8):

x_min, x_max = -3, 13
y_min, y_max = -6, 8

或者根据数据确定它们:

x_min = min([x for (x, y), z in data.items()])
y_min = min([y for (x, y), z in data.items()])
x_max = max([x for (x, y), z in data.items()])
y_max = max([y for (x, y), z in data.items()])

然后使用:

x_offset = abs(x_min)
y_offset = abs(y_min)

mat = np.zeros((y_max + y_offset + 1, x_max + x_offset + 1))    # (Row, column) becomes (y, x)

for (x, y), z in data.items():
    print(x, y)
    mat[int(y + y_offset), int(x + x_offset)] = z

pd.DataFrame(mat, columns=range(x_min, x_max + 1), 
                  index=range(y_min, y_max + 1))

然后使用以下内容进行绘图:

plt.imshow(mat, origin='lower', extent=[x_min, x_max + 1, 
                                        y_min, y_max + 1])

答案 1 :(得分:0)

numpy允许负索引 那么您可以使用:

np.rot90(matrix, 1)

将[0,0]移动到左下方

答案 2 :(得分:0)

Numpy不会对负索引产生错误,但是会从最后开始对其进行索引,这不是您想要的。 您为矩阵选择了错误的尺寸。下面的代码计算矩阵的大小以适合您的所有位置,然后将位置坐标移动到适合矩阵的位置,在这种情况下为-3和-6

xlim = (-3, 13)
ylim = (-6,8)

# your array dimension must be
dim = xlim[1] - xlim[0], ylim[1]-ylim[0]

matrix = np.zeros(dim)

for (x, y), z in data.items():
    # this will also work for +ve lower limit
    x_new = int(x-xlim[0])
    y_new = int(y-ylim[0])

    # negetive sign because we want the index to start from bottom left
    matrix[-x_new, y_new] = z

print(matrix)


# if you want to remove rows and colums with all zeros
new_matrix = matrix[np.sum(matrix, axis=1)>0]
new_matrix = new_matrix[:,np.sum(matrix, axis=0)>0].copy()
print("\n",new_matrix)