【问题标题】:How do I convert a dictionary with coordinates and frequencies to a matrix?如何将具有坐标和频率的字典转换为矩阵?
【发布时间】:2019-12-20 23:25:43
【问题描述】:

我有一本看起来像这样的字典:

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)未显示。

我尝试过这样做:

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

    matrix[y,x] = z

但是我遇到了负尺寸错误。

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

【问题讨论】:

  • 将dict转换成pandas df并绘图
  • 您的代码在我的电脑上运行良好
  • 你能“标准化”你的坐标吗?也就是说,如果最小 x 为 -3,则将 3 添加到 每个 x-co,从而移动您的原点。或者类似 x = int(x + abs(minx))。

标签: python pandas numpy dictionary plot


【解决方案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])

【讨论】:

  • 而 16 = maxX - minX = 13 - (-3)
  • 我喜欢这个答案。但是,当我print (mat) 时,值“12”(例如)实际上并不位于位置 (2,2) 而是位于位置 (9,11)。当我使用plt.imshow(mat) 时,y 轴也不是从 0 开始的。
  • 试过@tom 但实际点不在正确的位置。将尝试新的编辑!
  • 我也想知道 - 当使用 imshow(mat) 进行新编辑时,x,y 轴从 0 向上,而不是我定义的轴(xlim: -3, 13, ylim: -6 , 8) 即我将如何绘制 df? 编辑我使用extent=[-3,14, -6,8]查看范围
  • 如何使 x 和 y 偏移,以及数组中 0 的数量任意并取决于数据?
【解决方案2】:

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

np.rot90(matrix, 1)

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

【讨论】:

    【解决方案3】:

    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)
    

    【讨论】:

    • 我有点困惑,因为当我 print(matrix) 说位置 (2.0,2.0) 实际上并没有在数组中的 2.0,2.0 中索引,而是在 (9,5) 中..
    • 它正在移动索引,您的 xlim 是 -3 到 13,因此您在 -3 处的 x 坐标位于矩阵中的索引 -1(最后一行)处,而您的 x 坐标中的 13 位于索引 0 处矩阵。如果要将坐标的 2,2 映射到矩阵的 2,2 应该如何处理 -2,-2 索引?
    猜你喜欢
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-17
    • 1970-01-01
    相关资源
    最近更新 更多