我有以下几点 xy
numpy数组,表示一些三角形顶点的位置。
array([[[ 0.30539728, 49.82845203],
[ 0.67235022, 49.95042185],
[ 0.268982 , 49.95195348]],
[[ 0.268982 , 49.95195348],
[ 0.67235022, 49.95042185],
[ 0.27000135, 50.16334035]],
...
[[ 1.00647459, 50.25958169],
[ 0.79479121, 50.3010079 ],
[ 0.67235022, 49.95042185]],
[[ 0.79479121, 50.3010079 ],
[ 0.6886783 , 50.25867683],
[ 0.67235022, 49.95042185]]])
这里,是一个形状的数组 (10, 3, 2)
但也可能是 (5, 3, 2)
或 (18, 3, 2)
,你的名字。无论如何,它的形状 (N, 3, 2)
.我有另一个numpy数组 to_replace
形状 (4, 2)
但也可能是 (6, 2)
或 (7, 2)
但总是形状的 (M, 2)
:
array([[ 1.08267406, 49.88690993],
[ 1.1028248 , 50.01440407],
[ 0.74114309, 49.73183549],
[ 1.08267406, 49.88690993]])
它表示在我的第一个数组中可以找到的坐标对的位置。请注意,这些坐标对中的每一个都至少在我的第一个数组中出现一次。xy
最后,我有第三个数组。replace_by
何等 (8,)
形状 (M*2)
基于上面的说明),哪些值是用来准确地替换包含在 to_replace
在我第一次 xy
阵列。它看起来像这样。
array([ 0.87751214, 49.91866589, 0.88758751, 49.98241296, 0.70674665, 49.84112867, 0.87751214, 49.91866589])
所以基本上所有的对 [1.08267406, 49.88690993]
在 xy
应改为 [0.87751214, 49.91866589]
比如说,我现在的代码是这样的。
我现在的代码是这样的,但只有在以下情况下才有效 to_replace
和 replace_by
严形 (2, 2)
.
indices = (xy == to_replace[:, None][:, None])[0]
xy[indices] = replace_by
您可以使用 numpy.isclose 来比较行,然后用 .all(axis=2)
来找到所有最后一行都相同的地方。Numpy将广播每一行以适合 xy
形。
import numpy as np
xy = np.array([[[ 0.30539728, 49.82845203],
[ 0.67235022, 49.95042185],
[ 0.268982 , 49.95195348]],
[[ 0.268982 , 49.95195348],
[ 0.67235022, 49.95042185],
[ 0.27000135, 50.16334035]],
[[ 1.00647459, 50.25958169],
[ 0.79479121, 50.3010079 ],
[ 0.67235022, 49.95042185]],
[[ 0.79479121, 50.3010079 ],
[ 0.6886783 , 50.25867683],
[ 0.67235022, 49.95042185]]])
xy_start = xy.copy()
to_replace = np.array([[ 1.08267406, 49.88690993],
[ 1.1028248 , 50.01440407],
# [ 0.74114309, 49.73183549],
[ 0.6886783 , 50.25867683],
[ 1.08267406, 49.88690993]])
replace_by = np.array([ 0.87751214, 49.91866589, 0.88758751, 49.98241296, 0.70674665, 49.84112867, 0.87751214, 49.91866589])
replace_by_reshaped = replace_by.reshape(-1, 2)
for i, row in enumerate(to_replace):
xy[np.isclose(xy, row).all(axis=2)] = replace_by_reshaped[i]
print(xy_start)
# [[[ 0.30539728 49.82845203]
# [ 0.67235022 49.95042185]
# [ 0.268982 49.95195348]]
# [[ 0.268982 49.95195348]
# [ 0.67235022 49.95042185]
# [ 0.27000135 50.16334035]]
# [[ 1.00647459 50.25958169]
# [ 0.79479121 50.3010079 ]
# [ 0.67235022 49.95042185]]
# [[ 0.79479121 50.3010079 ]
# [ 0.6886783 50.25867683]
# [ 0.67235022 49.95042185]]]
print(xy)
# [[[ 0.30539728 49.82845203]
# [ 0.67235022 49.95042185]
# [ 0.268982 49.95195348]]
# [[ 0.268982 49.95195348]
# [ 0.67235022 49.95042185]
# [ 0.27000135 50.16334035]]
# [[ 1.00647459 50.25958169]
# [ 0.79479121 50.3010079 ]
# [ 0.67235022 49.95042185]]
# [[ 0.79479121 50.3010079 ]
# [ 0.70674665 49.84112867]
# [ 0.67235022 49.95042185]]]
编辑
.all(axis=2)
缩小轴=2至 True
如果沿轴线=2的所有数值都是 True
和 False
别的。我想小2d的例子已经说明了这里的情况。
>>> import numpy as np
>>> a = np.array([[0, 1], [0, 2], [3, 4]])
>>> a
array([[0, 1],
[0, 2],
[3, 4]])
>>> np.isclose(a, [0, 1])
array([[ True, True],
[ True, False],
[False, False]])
>>> np.isclose(a, [0, 1]).all(axis=1)
array([ True, False, False])
>>> a[np.isclose(a, [0, 1]).all(axis=1)]
array([[0, 1]])
>>> a[np.isclose(a, [0, 1]).all(axis=1)] = [12, 14]
>>> a
array([[12, 14],
[ 0, 2],
[ 3, 4]])
的 指数化 包(声明:我是它的作者)包含了以矢量化和优雅的方式解决这个问题的功能。
考虑到你所定义的数组,这个单行本应该可以解决这个问题。
import numpy_indexed as npi
npi.remap(xy.reshape(-1, 2), to_replace, replace_by.reshape(-1, 2)).reshape(-1, 3, 2)