numpy:插入数组代替元素

numpy: insert array in place of an element

输入:

import numpy as np

a = np.array([
    [0, 1, 0],
    [1, 0, 0]
])

期望的输出:

b = np.array([
    [[0, 0],[1, 1], [0, 0]],
    [[1, 1], [0, 0], [0, 0]]
])

我尝试过的:

b = np.where(a == 0, np.array([0, 0]), np.array([1, 1]))

上面的代码给了我一个ValueError: operands could not be broadcast together with shapes (<a's dimentions>) (2,) (2,)

编辑:我这边的例子不好。我认为让它变得简单会使它更具可读性。但是我不一定要 ones 代替 1 和 zeros 代替 0,并且输入不限于 0s 和 1s。相反,我希望输入类似于:

a = np.array([
    [0, 1, 0],
    [1, 2, 0]
])

输出为:

b = np.array([
    [[5, 6],[8, 2], [5, 6]],
    [[8, 2], [7, 4], [5, 6]]
])

你可以使用面具和numpy broadcasting

import numpy as np

a = np.array([[0, 1, 0],
              [1, 2, 0]])

d = {0: [5, 6],
     1: [8, 2],
     2: [7, 4]}

# Initialize b              
b = np.zeros((a.shape[0], a.shape[1], 2))

for k,v in d.items():

    m = a==k
    b += m[...,None] * np.tile(v, (a.shape[0], a.shape[1], 1))

b
array([[[5., 6.],
        [8., 2.],
        [5., 6.]],

       [[8., 2.],
        [7., 4.],
        [5., 6.]]])

您可以扩展维度然后沿新维度重复(或重复然后重塑):

np.repeat(np.expand_dims(a, axis=2), 2, axis=2)

输出:

[[[0 0]
  [1 1]
  [0 0]]

 [[1 1]
  [0 0]
  [0 0]]]

如果您想要不同的输出,现在您可以更轻松地将您的条件应用于新数组。

更新:针对一般情况对 post 进行的每次编辑:假设您有一个映射字典(取决于您的映射,解决方案可能会有所不同)

map_dict = {0: [5, 6],
     1: [8, 2],
     2: [7, 4]}

indexer = np.array([map_dict.get(i, [-1,-1]) for i in range(np.amax(a)+1)])[a]

或者在更具体的情况下,如果您的映射包括 0 和 max(a) 之间的所有整数,就像您的示例一样,请使用:

indexer = np.array([map_dict[i] for i in np.unique(a)])[a]

输出:

[[[5 6]
  [8 2]
  [5 6]]

 [[8 2]
  [7 4]
  [5 6]]]

假设 a 的元素是数组 c:

的有效行索引值
In [964]: c = np.array([[5,6], [8,2], [7,4]])                                                          
In [965]: a = np.array([[0,1,0],[1,2,0]])                                                              
In [966]: c[a,:]                                                                                       
Out[966]: 
array([[[5, 6],
        [8, 2],
        [5, 6]],

       [[8, 2],
        [7, 4],
        [5, 6]]])

这是对您的规范的最简单解释。如果 c 不是像这样的二维数组,或者 a 不只是映射到行,你将不得不做更多的工作来转换它们(并且很可能会丢失大部分 numpy数组优势).

我要强调这不是 'insert' 或 'in-place' 映射。 a保持不变。它是一个 (2,3) 数组,Out[966] 是一个 (2,3,2) 数组。