2017-01-11 6 views
4

С учетом двух массивов (А и В) различной формы, у меня, как произвести массив, содержащий конкатенацию каждой строки из А с каждой строки из В.конкатенация каждой строки комбинации двух массивов Numpy

Например Дано:

A = np.array([[1, 2], 
       [3, 4], 
       [5, 6]]) 

B = np.array([[7, 8, 9], 
       [10, 11, 12]]) 

хотел бы, чтобы произвести массив:

[[1, 2, 7, 8, 9], 
[1, 2, 10, 11, 12], 
[3, 4, 7, 8, 9], 
[3, 4, 10, 11, 12], 
[5, 6, 7, 8, 9], 
[5, 6, 10, 11, 12]] 

Я могу сделать это с итерации, но это очень медленно, поэтому ищет некоторую комбинацию numpy функций, которые могут воссоздавать выше, как эффективно насколько возможно (входные массивы A и B будут содержать до 10 000 строк, следовательно, чтобы избежать вложенных циклов).

ответ

5

Идеальная проблема, чтобы узнать о slicing и broadcasted-indexing.

Вот Векторизованное решение с использованием этих инструментов -

def concatenate_per_row(A, B): 
    m1,n1 = A.shape 
    m2,n2 = B.shape 

    out = np.zeros((m1,m2,n1+n2),dtype=A.dtype) 
    out[:,:,:n1] = A[:,None,:] 
    out[:,:,n1:] = B 
    return out.reshape(m1*m2,-1) 

Пример запуск -

In [441]: A 
Out[441]: 
array([[1, 2], 
     [3, 4], 
     [5, 6]]) 

In [442]: B 
Out[442]: 
array([[ 7, 8, 9], 
     [10, 11, 12]]) 

In [443]: concatenate_per_row(A, B) 
Out[443]: 
array([[ 1, 2, 7, 8, 9], 
     [ 1, 2, 10, 11, 12], 
     [ 3, 4, 7, 8, 9], 
     [ 3, 4, 10, 11, 12], 
     [ 5, 6, 7, 8, 9], 
     [ 5, 6, 10, 11, 12]]) 
+1

Это красиво! – MaxU

+1

Спасибо, отлично работает и имеет преимущество перед распределением выходного массива, поэтому у меня есть пространство для него. –

+1

@DaveChallis Вот и вся идея. С большими массивами любая операция стекирования - это просто * наказание *, говорящее об эффективности памяти/производительности. – Divakar

2

Ссылка: numpy.concatenate on record arrays fails when array has different length strings

import numpy as np 
from numpy.lib.recfunctions import stack_arrays 
from pprint import pprint 

A = np.array([[1, 2], 
       [3, 4], 
       [5, 6]]) 

B = np.array([[7, 8, 9], 
       [10, 11, 12]]) 

cartesian = [stack_arrays((a, b), usemask=False) for a in A 
               for b in B] 

pprint(cartesian) 

Выход:

[array([1, 2, 7, 8, 9]), 
array([ 1, 2, 10, 11, 12]), 
array([3, 4, 7, 8, 9]), 
array([ 3, 4, 10, 11, 12]), 
array([5, 6, 7, 8, 9]), 
array([ 5, 6, 10, 11, 12])]