2016-09-07 2 views
2

Я надеюсь, что кто-нибудь может помочь мне в следующем. У меня есть 2 списка массивов, которые должны быть связаны друг с другом. Каждый список обозначает определенный объект. arr1 и arr2 являются атрибутами этого объекта. Например:Объединить список массивов numpy и изменить форму.

import numpy as np 

arr1 = [np.array([1, 2, 3]), np.array([1, 2]), np.array([2, 3])] 
arr2 = [np.array([20, 50, 30]), np.array([50, 50]), np.array([75, 25])] 

Массивы связаны друг с другом, как в 1 в arr1, первый массив принадлежит к 20 в arr2 первого массива. Результат, который я ищу в этом примере, будет состоять из массива numpy размером 3,4. Столбцы стоят 0, 1, 2, 3 (числа в arr1, плюс 0), а строки заполняются соответствующими значениями arr2. Когда нет соответствующих значений эта ячейка должна быть 0. Пример:

array([[ 0, 20, 50, 30], 
     [ 0, 50, 50, 0], 
     [ 0, 0, 75, 25]]) 

Как бы связать эти два списка массивов и изменить их в нужном формате, как показано в приведенном выше примере?

Большое спасибо!

+0

В 'arr1' нет номера' 0'. – Dschoni

+0

@Dschoni В этом вопросе говорится: 'Когда нет соответствующих значений, эта ячейка должна быть 0'. – Divakar

+0

@Divakar: В вопросе говорится: «Столбцы стоят 0,1,2,3 (числа в arr1)» – Dschoni

ответ

3

Вот почти * Векторизованный подход -

lens = np.array([len(i) for i in arr1]) 

N = len(arr1) 
row_idx = np.repeat(np.arange(N),lens) 
col_idx = np.concatenate(arr1) 

M = col_idx.max()+1 
out = np.zeros((N,M),dtype=int) 
out[row_idx,col_idx] = np.concatenate(arr2) 

*: Почти из понимания петли в начале, но это должно быть вычислительно незначительно, поскольку это не предполагает какие-либо вычислений там.

+0

Работает как очарование! Быстрый и аккуратный код, отлично! – cf2

+0

@ cf2 Без проблем! Возможно, отредактируйте вопрос, чтобы уточнить это сомнение в '0' в' arr1'? – Divakar

+0

Хорошая точка. Надеюсь, теперь все ясно. Еще раз спасибо! – cf2

1

Вот решение с петлями. Показаны каждый шаг в деталях.

import numpy as np 

arr1 = [np.array([1, 2, 3]), np.array([1, 2]), np.array([2, 3])] 
arr2 = [np.array([20, 50, 30]), np.array([50, 50]), np.array([75, 25])] 

maxi = [] 
for i in range(len(arr1)): 
    maxi.append(np.max(arr1[i])) 
maxi = np.max(maxi) 
output = np.zeros((len(arr2),maxi)) 
for i in range(len(arr1)): 
    for k in range(len(arr1[i])): 
     output[i][k]=arr2[i][k] 
+0

Спасибо за то, что вы указали детали каждого шага. Очень полезно! – cf2

0

Это прямой подход, только один уровень итерации:

In [261]: res=np.zeros((3,4),int) 
In [262]: for i,(idx,vals) in enumerate(zip(arr1, arr2)): 
    ...:  res[i,idx]=vals 
    ...:  
In [263]: res 
Out[263]: 
array([[ 0, 20, 50, 30], 
     [ 0, 50, 50, 0], 
     [ 0, 0, 75, 25]]) 

Я подозреваю, что это быстрее, чем @Divakar's подход для этого примера. И он должен оставаться конкурентоспособным, если количество столбцов немного больше, чем количество строк.

Смежные вопросы