按索引选择不同形状的numpy数组并将其写回

时间:2018-02-22 16:04:38

标签: python numpy

我正在寻找索引策略如何从原始数组(左侧)中选择子数组(右侧),然后用子代替原始数组阵列()。有一些索引可以为每行选择 ,例如对于第一行,它们是[1,3,0],最后一行是[4,6,2]。 下图中的完整选择矩阵如下所示:

[[1,3,0],
 [2,3,2],
 [4,0,6],
 [1,4,0],
 [4,6,2]]

到目前为止,我只能循环遍历原始数组的行并替换列索引处的值。 是否有没有循环的解决方案?

         +--------------------------------------+
         |                                      |
         |           +-----------------------+  |
         |           |                       |  |
         |   +----------------------------+  |  |
         |   |       |                    |  |  |
         |   |       |                    |  |  |
         |   |       |                    |  |  |
         |   |       |                    |  |  |
         +   +       +                    v  v  v
array([[ 0,  1,  2,  3,  4,  5,  6],      1, 3, 0,
       [ 7,  8,  9, 10, 11, 12, 13],      9,10,9,
       !14, 15, 16, 17,!18, 19,!20],     18,14,20,
       [21, 22, 23, 24, 25, 26, 27],     22,25,21,
       [28, 29, 30, 31, 32, 33, 34]])    32,34,30
                +        +       +        ^  ^  ^
                |        |       |        |  |  |
                |        +----------------+  |  |
                |                |           |  |
                |                +-----------+  |
                |                               |
                +-------------------------------+

最终数组是原始数组,替换了子数组中的最后一个索引(从原始数组中选择。

                       +------------+
array([[ 0,  1,  2,  3,| 1,  3,  0],|
       [ 7,  8,  9, 10,| 9, 10,  9],|
       [14, 15, 16, 17,|18, 14, 20],|
       [21, 22, 23, 24,|22, 25, 21],|
       [28, 29, 30, 31,|32, 34, 30]]|
                       +------------+

循环解决方案:

selection = np.array([[1,3,0],
                     [2,3,2],
                     [4,0,6],
                     [1,4,0],
                     [4,6,2]])
y = np.arange(35).reshape(5,7)
s = y.shape[1] - selection.shape[1]
e = y.shape[1]
for i in range(0, y.shape[0]):
    y[i, s:e] = y[i, selection[i]]

>>> y
array([[ 0,  1,  2,  3,  1,  3,  0],
       [ 7,  8,  9, 10,  9, 10,  9],
       [14, 15, 16, 17, 18, 14, 20],
       [21, 22, 23, 24, 22, 25, 21],
       [28, 29, 30, 31, 32, 34, 30]])

2 个答案:

答案 0 :(得分:2)

您可以通过创建行的索引来实现:

import numpy as np

a = np.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, 25, 26, 27],
              [28, 29, 30, 31, 32, 33, 34]])

idx = np.array([[1,3,0],
                [2,3,2],
                [4,0,6],
                [1,4,0],
                [4,6,2]])

rows = np.tile(np.arange(len(idx)), [idx.shape[1], 1]).T
# This array looks like this:
# [[0, 0, 0],
#  [1, 1, 1],
#  [2, 2, 2],
#  [3, 3, 3],
#  [4, 4, 4]]

a[:, -idx.shape[1]:] = a[rows, idx]
print(a)

输出:

array([[ 0,  1,  2,  3,  1,  3,  0],
       [ 7,  8,  9, 10,  9, 10,  9],
       [14, 15, 16, 17, 18, 14, 20],
       [21, 22, 23, 24, 22, 25, 21],
       [28, 29, 30, 31, 32, 34, 30]])

答案 1 :(得分:2)

使用broaodcasting和高级索引:

>>> y[:, 4:] = y[np.arange(5)[:, None], selection]
>>> y
array([[ 0,  1,  2,  3,  1,  3,  0],
       [ 7,  8,  9, 10,  9, 10,  9],
       [14, 15, 16, 17, 18, 14, 20],
       [21, 22, 23, 24, 22, 25, 21],
       [28, 29, 30, 31, 32, 34, 30]])