numpy: вставить массив вместо элемента - PullRequest
1 голос
/ 28 апреля 2020

Ввод:

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, и ввод не ограничен 0 и 1. Вместо этого я хочу, чтобы на входе было что-то вроде:

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

, а на выходе было:

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

Ответы [ 3 ]

2 голосов
/ 28 апреля 2020

Вы можете расширить измерения и затем повторить вдоль нового измерения (или повторить, а затем изменить форму):

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

Вывод:

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

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

И если вы хотите иметь другой вывод, теперь вы можете проще применить ваше условие к новому массиву.

ОБНОВЛЕНИЕ : за редактирование поста для общего случая: при условии, что у вас есть словарь сопоставлений (в зависимости от вашего сопоставления решение может отличаться)

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]

или в более конкретном случае c, если ваше отображение включает все целые числа от 0 до max (a), как в вашем примере, используйте это:

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

output:

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

 [[8 2]
  [7 4]
  [5 6]]]
1 голос
/ 28 апреля 2020

Предполагая, что элементы 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 ).

Я должен подчеркнуть, что это не отображение «вставки» или «на месте». a остается без изменений. Это массив (2,3), Out[966] массив (2,3,2).

1 голос
/ 28 апреля 2020

Можно использовать маску и numpy вещать

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.]]])

...