連結

2017-01-11 13 views
4

異なる形状の二つの配列(AおよびB)を考えると、私はB.連結

からすべての行とからすべての行の連結を含む配列を生成するようにしました例えば与えられた:私は反復でこれを行うことができます

[[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 = np.array([[1, 2], 
       [3, 4], 
       [5, 6]]) 

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

は配列を生成したいと思います(入力配列AとBは最大10,000行のサイズになり、ネストされたループを避けるように見えます)。

答えて

5

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