【问题标题】:Replace elements in an Nx3x2 numpy array with elements located in an Mx2 numpy array将 Nx3x2 numpy 数组中的元素替换为 Mx2 numpy 数组中的元素
【发布时间】:2020-06-02 23:13:49
【问题描述】:

我有以下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)。 我有另一个形状为(4, 2) 的numpy 数组to_replace,但它也可以是(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),基于​​上面的指示),哪些值旨在完全替换我的第一个xy数组中to_replace中包含的值.它看起来像这样:

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

所以基本上xy 中的所有[1.08267406, 49.88690993] 对都应该替换为[0.87751214, 49.91866589]

我当前的代码看起来像这样,但它只有在 to_replacereplace_by 严格符合 (2, 2) 的情况下才有效。

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

我在numberanswersalready looked 并实际上受到了其中一些的启发,但我仍然无法让它发挥作用。

【问题讨论】:

    标签: python python-3.x numpy numpy-ndarray array-broadcasting


    【解决方案1】:

    您可以使用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 的所有值都是TrueFalse 否则。我认为小 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]])
    

    【讨论】:

    • 谢谢,它正在工作。您能否提供更多关于此.all(axis=2) 的目的以及它在做什么的信息?我不确定魔术是如何发生的。
    【解决方案2】:

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

    鉴于您定义的数组,这个单行应该可以解决问题:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-02
      • 2018-03-30
      • 1970-01-01
      • 2021-05-15
      • 2019-04-08
      • 2019-03-30
      • 1970-01-01
      相关资源
      最近更新 更多