【问题标题】:Convert dictionary of tuple(x,y): value to x[], y[], value[][], where indices correspond?将 tuple(x,y): value 的字典转换为 x[], y[], value[][],索引对应的地方?
【发布时间】:2019-02-08 11:03:51
【问题描述】:

我正在尝试将字典转换为可以使用 matplotlib 绘制为轮廓的形式。字典的键是 X,Y 坐标的元组,值是该坐标的读数。我想将它们放入一个三个 numpy 数组、一个 x 坐标的一维数组、一个 y 坐标的一维数组和一个二维值数组。 x,y 数组各自的索引应该对应字典中定义的二维数组中值的索引。

修改以更好地定义问题:

示例输入数据: 字典

(0,0): 1
(1.5,0): 2
(0,1.5): 3
(1.5,1.5): 4

我想要什么

x = [0,1.5]
y = [0,1.5]
values = [[1,2],[3,4]]

我有

for key in corr_data.items():
    X.append(key[0])
    Y.append(key[1])
X = list(dict.fromkeys(X))
Y = list(dict.fromkeys(Y))

它获取 x 和 y 数组,但值数组让我无法理解。

感谢任何帮助

【问题讨论】:

  • 到目前为止你做了什么?
  • 请发布一些示例数据。如果 x 和 y 是 1d 并且值数组应该是 2d,则必须有重复的 x 和 y 值。特别是对于非整数值,这可能很棘手。你打算用 matplotlib 绘制这个吗?
  • 提供真实样本符合您的最大利益。如果索引不是 0、1、2 等,甚至不是整数,则基于当前示例的任何简单答案可能实际上不适用于您的情况。

标签: python arrays numpy dictionary


【解决方案1】:

您可以简单地遍历您的 dict 并创建您的列表,并可能将该列表转换为 numpy.ndarray

x = []
y = []
vals = np.zeros(your_grid_shape)
for ((i,j), v) in your_dict.iteritems():
    x.append(i)
    y.append(j)
    vals[i, j] = v
x = list(set(x))
y = list(set(y))

【讨论】:

  • 是的,这是我遇到的问题,x 和 y 包含每个坐标的多个值
  • 嗨,我想这差不多了,但不幸的是,i 和 j 坐标值不是正整数(对不起,这在样本数据中具有误导性),所以行 vals[i, j] = v 不会工作
【解决方案2】:

我在这里是一个“自包含”的答案,因为我首先生成一些输入数据,然后将其转换为字典,然后再转换回原始数组。在途中,我添加了一些随机噪声以保持 x 和 y 值彼此接近,但仍使它们独一无二。在this answer 之后,可以通过首先对值进行四舍五入然后使用np.unique 来找到所有彼此“接近”的值的列表。

mport numpy as np

##generating some input data:
print('input arrays')
xvals = np.linspace(1,10, 5)
print(xvals)
yvals = np.linspace(0.1, 0.4, 4)
print(yvals)
xvals, yvals = np.meshgrid(xvals, yvals)

##adding some noise to make it more interesting:
xvals += np.random.rand(*xvals.shape)*1e-3
yvals += np.random.rand(*yvals.shape)*1e-5

zvals = np.arange(xvals.size).reshape(*xvals.shape)
print(zvals)

input_dict ={
    (i,j): k for i,j,k in zip(
        list(xvals.flatten()), list(yvals.flatten()), list(zvals.flatten())
    )
}

##print(input_dict)


x,y,z = map(np.array,zip(*((x,y,z) for (x,y),z in input_dict.items())))

##this part will need some tweaking depending on the size of your
##x and y values
xlen = len(np.unique(x.round(decimals=2)))
ylen = len(np.unique(y.round(decimals=3)))


x = x.round(decimals=2).reshape(ylen,xlen)[0,:]
y = y.round(decimals=3).reshape(ylen,xlen)[:,0]
z = z.reshape(ylen,xlen)

print('\n', 'output arrays')

print(x)
print(y)
print(z)

输出如下:

input arrays
[ 1.    3.25  5.5   7.75 10.  ]
[0.1 0.2 0.3 0.4]
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]]

 output arrays
[ 1.    3.25  5.5   7.75 10.  ]
[0.1 0.2 0.3 0.4]
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]]

旧答案:

这个答案有很多假设,主要是因为问题中没有足够的信息。但是,假设

  1. x 和 y 值的顺序与示例数据中的一样好
  2. x 和 y 值是完整的

人们可以通过列表理解和重塑 numpy ndarrays 来解决这个问题:

import numpy as np

input_dict = {
    (0,0): 1,
    (1,0): 2,
    (0,1): 3,
    (1,1): 4,
}

x,y,z = map(np.array,zip(*((x,y,z) for (x,y),z in input_dict.items())))

xlen = len(set(x))
ylen = len(set(y))

x = x.reshape(xlen,ylen)[0,:]
y = y.reshape(xlen,ylen)[:,0]
z = z.reshape(xlen,ylen)


print(x)
print(y)
print(z)

给了

[0 1]
[0 1]
[[1 2]
 [3 4]]

希望这会有所帮助。

PS:如果 x 和 y 值不一定按照发布的示例数据建议的顺序,仍然可以通过一些巧妙的排序来解决问题。

【讨论】:

  • 嗨,前两个假设是正确的,但不幸的是第三个假设不正确。我会尝试考虑如何修改它
  • @PeterScanlon 我改变了我的解决方案,通过计算有多少不同的 x 和 y 值来摆脱第三个假设(正方形)——请看一下。
  • @PeterScanlon 我刚刚在您对另一个答案的评论中看到您的 x 和 y 不是整数。在这种情况下,set(x) 可能无法按预期工作,因为浮点数不精确。在这种情况下,可能需要提供 x 和 y 值的数量。在比较值时可能会引入一些容差,但我必须四处看看。
  • @PeterScanlon 我更新了我的答案以展示如何对非整数 x 和 y 完成。
【解决方案3】:

在 REPL 中

In [9]: d = {(0,0): 1, (1,0): 2, (0,1): 3, (1,1): 4}
In [10]: x = set(); y = set()
In [11]: for xx, yy in d.keys():
    ...:     x.add(xx)
    ...:     y.add(yy)
In [12]: x
Out[12]: {0, 1}
In [13]: x = sorted(x) ; y = sorted(y)
In [14]: x
Out[14]: [0, 1]
In [15]: v = [[d.get((xx,yy)) for yy in y] for xx in x]
In [16]: v
Out[16]: [[1, 3], [2, 4]]

如您所见,我的结果与您的示例不同,但x 对应于行,y 对应于列是很常见的。如果您想要更多地理约定,请在最终列表理解中交换 xy

作为脚本,我们可以编写

def extract{d}:
    x = set(); y = set()
    for xx, yy in d.keys():
        x.add(xx)
        y.add(yy)
    x = sorted(x) ; y = sorted(y)
    v = [[d.get((xx,yy)) for yy in y] for xx in x]
    # = [[d.get((xx,yy)) for xx in x] for yy in y]
    return x, y, v

【讨论】:

  • 你能假设 x 和 y 值在 sets 中表现得很好,即使它们是浮点数?
  • @ThomasKühn 当我开始写我的答案时,我有 整数 的元组作为键...我会检查并最终改变我的答案,感谢提醒,ciao .
  • @ThomasKühn set((1.2, 3.4, math.sqrt(2))) 返回{1.2, 1.4142135623730951, 3.4} 所以我想我的答案可以保持原样......
  • 我的意思是浮点应该相等的情况,但不完全是因为浮点不精确。例如here 我的意思。老实说,我想知道这是否可以假设,因为它也会使我的第一个答案非常好。
  • @ThomasKühn 好吧,只有 OP 知道......例如,从文字实例化的浮点数是否应该始终产生相同的 FP 编号,不是吗? — otoh,可以从测量设备中读取浮点数,在测量不确定性范围内,相同的值应该有两种不同的表示形式(我们可以考虑使用Decimal 和舍入,但它会变得更复杂)。我再重复一遍,只有 OP 可以告诉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-06
  • 2011-06-12
  • 2022-11-13
  • 2011-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多