首页 > 解决方案 > 将 2D numpy 数组转换为相同大小的数组,其中包含在 1D 数组中找到元素的位置

问题描述

我有 2 个数组,我们称它们为PointsLine

Points 是一个二维数组,带有Points.shape = (M, 3),如:

Points = array([p1, q1, r1], 
               [p2, q2, r2],
               [p3, q3, r3],
                ...,          
               [pM, qM, rM])

p, q, r 是整数,没有特定的顺序,每个代表一个特定的点。对于任何特定行,所有点 p、q、r 都是不同的。但是一个特定的整数可以在Points中出现多次(例如,q1 = p7 = p19 = r309 = 52106)。

另一方面,LineLine.shape = (N, )是一维数组,其中Line = array([l1, l2, l3, ..., lN]). 这些术语l还表示整数,如Points。通常,M比 大得多N

这是问题所在:Line中的所有整数在Points中至少出现一次,但大多数 p、q、r 不出现在Line中。我想构造一个新的二维数组Points_index,其形状与Points相同,例如:

为了说明,如果:

Points = array([ 50,  156,   10],
               [  5,  509, 2225],
               [599, 1006,    1],
               [  1,    5,  156], 
               [ 50,  509,   47]) 

Line = array([50, 5, 156, 47])

那么Points_index是:

array([1, 3, 0],  
      [2, 0, 0],  
      [0, 0, 0],  
      [0, 2, 3],  
      [1, 0, 4])

我想尽快做到这一点。我试过in1d了,但它给出了一个真/假掩码而不是索引。我努力了 :

Points_index_123 = {}
for i in range(3):
    extr_i = np.zeros_like(Points[:, i])
    for k, el in enumerate(Points[:, i]):
        if el in Line:
            extr_i[k] = np.where(el == Line)[0]+1
        else:
            extr_i[k] = 0
    Points_index_123[i] = extr_i

Points_index = np.stack((Points_index_123[0], 
                         Points_index_123[1],
                         Points_index_123[2]), axis = 1)

但我觉得这太慢了(2个嵌套循环)。有什么办法吗?

标签: pythonarraysnumpy

解决方案


尝试这个:

import numpy as np
idx = np.zeros(Points.shape)
i, j, k = np.nonzero(Lines[:, None, None] == Points)
idx[j, k] = i + 1

idx
# array([[1., 3., 0.],
#        [2., 0., 0.],
#        [0., 0., 0.],
#        [0., 2., 3.],
#        [1., 0., 4.]])

使用数组中每个元素的广播比较,然后找出位置,然后(花哨)索引数组以获取它们各自的位置。LinesPointsTruenp.nonzero()idx

i由于您需要Lines1 索引中的位置,因此添加了 +1 。


推荐阅读