将Nx3x2 numpy阵列中的元素替换为Mx2 numpy阵列中的元素

2024-10-04 11:26:14 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下xynumpy数组,它表示一些三角形顶点的位置:

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,其中的shape (8,)(或者基于上面的指示的shape (M*2)),它的值正好替换第一个xy数组中to_replace中包含的值。看起来是这样的:

array([ 0.87751214, 49.91866589,  0.88758751, 49.98241296,  0.70674665, 49.84112867,  0.87751214, 49.91866589])

因此,基本上,{}中的所有对[1.08267406, 49.88690993]都应该被[0.87751214, 49.91866589]代替

我当前的代码看起来是这样的,但它只有在to_replacereplace_by严格按形状(2, 2)时才起作用

indices = (xy == to_replace[:, None][:, None])[0]
xy[indices] = replace_by

我在一个already{a2}的number{a4}中的一个number中得到了一些灵感,但我仍然无法让它发挥作用


Tags: tonumpynonenumberby数组arrayreplace
2条回答

您可以使用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上的所有值都是TrueFalse,则将轴=2收缩到True。我认为这个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]])

{a1}包(免责声明:我是它的作者)包含以矢量化和优雅的方式解决此问题的功能

给定您定义的数组,这一行程序应该可以:

import numpy_indexed as npi    
npi.remap(xy.reshape(-1, 2), to_replace, replace_by.reshape(-1, 2)).reshape(-1, 3, 2)

相关问题 更多 >