我有两个数据框,其中一个有两列(图形边缘列表),另一个是这些点的位置。我想在第一个数据帧中搜索并替换每个点的x和y坐标,而不是替换两个单独的数据帧中的点。首先,我将数据帧转换为numpy数组。 例如,假设我们以xx作为边缘列表,以yy作为坐标,如下所示:
xx= np.array([(4,2),(3,5)])
yy=np.array([(2,6,7),(5,5,6),(4,8,9),(3,2,2)])
所以xx是我们的边缘点,yy是每个点的坐标(例如,点4的x值为8,y值为9) 然后我尝试用对应于x坐标值的节点替换节点:
zz=[]
for i in np.nditer(xx,order='F'):
cc=np.where(yy[:,0]==i)
zz.append(cc[0][0])
zz=np.array(zz)
q=[]
for i in range(xx.size):
q.append(yy[zz[i],1])
xcoordinates=np.array(q).reshape(int(xx.size/2),2)
但是重塑后结果不正确:
array([[8, 2],
[6, 5]])
请让我知道如何获得x的结果:
[8,6]
[2,5]
我是python的新手,无法理解复杂的代码。
答案 0 :(得分:0)
需要使用第二个数组,但是您可以创建一个可以用xx
进行索引的查找数组。
u = np.empty(yy[:, 0].max() + 1, dtype=yy.dtype)
u[yy[:, 0]] = yy[:, 1]
u[xx]
array([[8, 6],
[2, 5]])
这个答案有两个假设,您应该考虑一下。
1)yy
必须是唯一的,并且必须具有整数dtype
2)xx
必须遵循yy.min() < xx < yy.max()
,否则您将获得IndexError
3)xx
的所有值都必须在y[:, 0]
中,否则您将在映射中返回垃圾值。
答案 1 :(得分:0)
让我们定义一个小辅助函数-将xx
的值与yy
的第一列进行匹配,并从第二列返回该值。
def foo(x):
return yy[yy[:,0]==x, 1].item()
并对其进行一些测试:
In [101]: foo(3)
Out[101]: 2
In [102]: foo(4)
Out[102]: 8
让我们使用nditer
代替xx.flat
作为一维迭代器。
In [103]: for x in xx.flat:
...: print(foo(x))
...:
8
6
2
5
或者在列表理解中做同样的事情:
In [104]: [foo(x) for x in xx.flat]
Out[104]: [8, 6, 2, 5]
并使用reshape
将其转换回与xx
形状相同的数组:
In [105]: np.reshape([foo(x) for x in xx.flat],xx.shape)
Out[105]:
array([[8, 6],
[2, 5]])
我也喜欢frompyfunc
作为将标量函数应用于数组元素的方法。在测试中,它可以比更直接的迭代快2倍,但仍然易于使用且没有错误:
In [106]: np.frompyfunc(foo,1,1)(xx)
Out[106]:
array([[8, 6],
[2, 5]], dtype=object)
但是另一个答案显示了如何在没有Python级别迭代的情况下做同样的事情。
另一种“向量化”方法:
将xx
的所有值与yy
的第一列进行比较。结果是一个3d布尔数组:
In [107]: xx[...,None]==yy[:,0]
Out[107]:
array([[[False, False, True, False],
[ True, False, False, False]],
[[False, False, False, True],
[False, True, False, False]]])
where
是一个3元素元组。 2个元素索引xx
,最后一个yy
:
In [108]: np.where(xx[...,None]==yy[:,0])
Out[108]: (array([0, 0, 1, 1]), array([0, 1, 0, 1]), array([2, 0, 3, 1]))
In [109]: yy[np.where(xx[...,None]==yy[:,0])[2],1]
Out[109]: array([8, 6, 2, 5])