Performance Numpy从每个Numpy数组行中选择不同数量的第一个元素

Performance Numpy从每个Numpy数组行中选择不同数量的第一个元素,performance,numpy,vectorization,Performance,Numpy,Vectorization,我想从矩阵中选择不同数量的第一个元素。 数字在数组中指定。 结果是一维数组。 例如: a = np.arange(25).reshape([5, 5]) numbers = np.array([3, 2, 0, 1, 2]) 我想要这个结果: [0, 1, 2, 5, 6, 15, 20, 21] 没有for循环。让我们使用一些魔法吧 样本运行- In [161]: a Out[161]: array([[ 0, 1, 2, 3, 4], [ 5, 6, 7,

我想从矩阵中选择不同数量的第一个元素。 数字在数组中指定。 结果是一维数组。 例如:

a = np.arange(25).reshape([5, 5])
numbers = np.array([3, 2, 0, 1, 2])
我想要这个结果:

[0, 1, 2, 5, 6, 15, 20, 21]
没有for循环。

让我们使用一些魔法吧

样本运行-

In [161]: a
Out[161]: 
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24]])

In [162]: numbers
Out[162]: array([3, 2, 0, 1, 2])

In [163]: numbers[:,None] > np.arange(a.shape[1]) # Mask to select elems
Out[163]: 
array([[ True,  True,  True, False, False],
       [ True,  True, False, False, False],
       [False, False, False, False, False],
       [ True, False, False, False, False],
       [ True,  True, False, False, False]], dtype=bool)

In [164]: a[numbers[:,None] > np.arange(a.shape[1])] # Select w/ boolean indexing
Out[164]: array([ 0,  1,  2,  5,  6, 15, 20, 21])
让我们用点魔法吧

样本运行-

In [161]: a
Out[161]: 
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19],
       [20, 21, 22, 23, 24]])

In [162]: numbers
Out[162]: array([3, 2, 0, 1, 2])

In [163]: numbers[:,None] > np.arange(a.shape[1]) # Mask to select elems
Out[163]: 
array([[ True,  True,  True, False, False],
       [ True,  True, False, False, False],
       [False, False, False, False, False],
       [ True, False, False, False, False],
       [ True,  True, False, False, False]], dtype=bool)

In [164]: a[numbers[:,None] > np.arange(a.shape[1])] # Select w/ boolean indexing
Out[164]: array([ 0,  1,  2,  5,  6, 15, 20, 21])

我有一个巨大的矩阵,我只需要选择第一个元素的一小部分。因此,这种方法将构建一个巨大的掩模矩阵,以获得非常少量的数据。所以渐近解将是O(N*N),而不是O(N)。也许“for”循环会更快。有不同的方法来解决这个问题吗?@Stepochkin你用这种方法的内存不足吗?如果没有,这仍然是非常有效的。输入数组的数据大小是什么?作为一个布尔数组,内存需求将是
O(N*N)/8
。我用矩阵形状(10000,2000)调用了100次@Stepochkin使用这种方法是否内存不足?不,我有足够的内存。我尝试了Cython实现,得到了快50倍的函数。我有一个巨大的矩阵,我只需要选择第一个元素的一小部分。因此,这种方法将构建一个巨大的掩模矩阵,以获得非常少量的数据。所以渐近解将是O(N*N),而不是O(N)。也许“for”循环会更快。有不同的方法来解决这个问题吗?@Stepochkin你用这种方法的内存不足吗?如果没有,这仍然是非常有效的。输入数组的数据大小是什么?作为一个布尔数组,内存需求将是
O(N*N)/8
。我用矩阵形状(10000,2000)调用了100次@Stepochkin使用这种方法是否内存不足?不,我有足够的内存。我尝试了Cython的实现,得到了比Cython快50倍的功能。