2017-01-24 25 views
5

मैं आयाम 3Nx3N के साथ चार वर्ग मैट्रिक्स है, ए, बी, सी और डीविभिन्न सरणियों से एक सरणी में अनुकूलन काम - NumPy

मैं उन्हें एक ही मैट्रिक्स में संयोजित करना चाहते हैं कहा जाता है। छोरों के लिए कोड साथ है निम्नलिखित: एक numpythonic तरह से छोरों के लिए पिछले लिखने के

import numpy 
N = 3 
A = numpy.random.random((3*N, 3*N)) 
B = numpy.random.random((3*N, 3*N)) 
C = numpy.random.random((3*N, 3*N)) 
D = numpy.random.random((3*N, 3*N)) 

final = numpy.zeros((6*N, 6*N)) 

for i in range(N): 
    for j in range(N): 
     for k in range(3): 
      for l in range(3): 
       final[6*i + k][6*j + l] = A[3*i+k][3*j+l] 
       final[6*i + k + 3][6*j + l + 3] = B[3*i+k][3*j+l] 
       final[6*i + k + 3][6*j + l] = C[3*i+k][3*j+l] 
       final[6*i + k][6*j + l + 3] = D[3*i+k][3*j+l] 

क्या यह संभव है?

+0

(ऑफ-विषय) | मैं खुद से सोच रहा था, केवल एक बार मैंने सुना है कि "numpythonic" SO पर कुछ अन्य व्यक्ति था। लेकिन फिर मैंने जांच की और वह भी आप थे :) – miradulo

+1

@ लगभग एक * टॉनिक * मिच। – Divakar

+0

हां, मैं एक न्यूम्प्थोनिक तरीके से लूप बनाने के विभिन्न तरीकों से लड़ रहा हूं। आंख एक गलती है, यह शून्य होना चाहिए। – NunodeSousa

उत्तर

4

बहु-आयामी टेंसर/सरणी में array-slicing का अभ्यास करने के लिए बड़ी समस्या!

हम आउटपुट सरणी को बहु-आयामी 6D सरणी के रूप में प्रारंभ करेंगे और बस इसे टुकड़ा कर लेंगे और चार एरे को 4D सरणी के रूप में पुनः आकार दिया जाएगा। इरादा किसी भी स्टैकिंग/कॉन्सटेनेटिंग से बचने के लिए है क्योंकि यह विशेष रूप से महंगा होगा क्योंकि बड़े सरणी के साथ काम करते हुए इनपुट एरे के दोबारा बदलने के साथ काम करना होगा, जो केवल विचार होंगे।

यहाँ कार्यान्वयन है -

out = np.zeros((N,2,3,N,2,3),dtype=A.dtype) 
out[:,0,:,:,0,:] = A.reshape(N,3,N,3) 
out[:,0,:,:,1,:] = D.reshape(N,3,N,3) 
out[:,1,:,:,0,:] = C.reshape(N,3,N,3) 
out[:,1,:,:,1,:] = B.reshape(N,3,N,3) 
out.shape = (6*N,6*N) 

बस में और व्याख्या करने के लिए, हम था:

  |------------------------ Axes for selecting A, B, C, D 
np.zeros((N,2,3,N,2,3),dtype=A.dtype) 
        |------------------------- Axes for selecting A, B, C, D 

इस प्रकार, लंबाई (2x2) = 4 की उन दो कुल्हाड़ियों (दूसरा और पांचवें) के बीच चयन करने के लिए इस्तेमाल किया गया चार इनपुट।

रनटाइम परीक्षण

प्रयास -

def original_app(A, B, C, D): 
    final = np.zeros((6*N,6*N),dtype=A.dtype) 
    for i in range(N): 
     for j in range(N): 
      for k in range(3): 
       for l in range(3): 
        final[6*i + k][6*j + l] = A[3*i+k][3*j+l] 
        final[6*i + k + 3][6*j + l + 3] = B[3*i+k][3*j+l] 
        final[6*i + k + 3][6*j + l] = C[3*i+k][3*j+l] 
        final[6*i + k][6*j + l + 3] = D[3*i+k][3*j+l] 
    return final 

def slicing_app(A, B, C, D): 
    out = np.zeros((N,2,3,N,2,3),dtype=A.dtype) 
    out[:,0,:,:,0,:] = A.reshape(N,3,N,3) 
    out[:,0,:,:,1,:] = D.reshape(N,3,N,3) 
    out[:,1,:,:,0,:] = C.reshape(N,3,N,3) 
    out[:,1,:,:,1,:] = B.reshape(N,3,N,3) 
    return out.reshape(6*N,6*N) 

समय और सत्यापन -

In [147]: # Setup input arrays 
    ...: N = 200 
    ...: A = np.random.randint(11,99,(3*N,3*N)) 
    ...: B = np.random.randint(11,99,(3*N,3*N)) 
    ...: C = np.random.randint(11,99,(3*N,3*N)) 
    ...: D = np.random.randint(11,99,(3*N,3*N)) 
    ...: 

In [148]: np.allclose(slicing_app(A, B, C, D), original_app(A, B, C, D)) 
Out[148]: True 

In [149]: %timeit original_app(A, B, C, D) 
1 loops, best of 3: 1.63 s per loop 

In [150]: %timeit slicing_app(A, B, C, D) 
100 loops, best of 3: 9.26 ms per loop 
+0

कमांड 'numpy.allclose (आउट, फाइनल)' रिटर्न ट्रू: यह सुनिश्चित करता है कि हम यह सुनिश्चित करते हैं कि हम –

+0

@GuillaumeJacquenot को पुष्टि के लिए धन्यवाद देना चाहते हैं! सत्यापन भाग के साथ भी रनटाइम परीक्षण जोड़ा गया। – Divakar

1

तुम सिर्फ concat कर सकते हैं उन्हें

concat ए और बी क्षैतिज concat सी और डी क्षैतिज

सीडी की खड़ी

उदाहरण conjucntion साथ एबी के संयोजन के रूप concat:

AB = numpy.concatenate([A,B],1) 
CD = numpy.concatenate([C,D],1) 
ABCD = numpy.concatenate([AB,CD],0) 

मुझे उम्मीद है कि मदद करता है :)

+0

परिणाम अपेक्षित नहीं है: 'numpy.allclose (एबीसीडी, अंतिम) 'झूठी –

+0

लौटाता है क्या आपने केवल एबीसीडी प्रिंट करने की कोशिश की? यह वांछित मैट्रिक्स होल्ड। आप मैट्रिक्स को मैन्युअल रूप से प्रिंट करने वाले मानों को जांच सकते हैं (यह) यह देखने के लिए कि क्या अपेक्षित है। उदाहरण/परीक्षण – epattaro

+0

के रूप में मामूली 2x2 मैट्रिक्स के साथ प्रयास करें आप सही रास्ते पर हैं। 'बमत' के साथ मेरा जवाब इस तरह के 'concatenate' करता है। लेकिन ओपी का लेआउट अधिक जटिल है, कुछ reshaping और अक्ष स्वैपिंग की आवश्यकता है। – hpaulj

2

मैं सामान्य टिप्पणियों

के एक जोड़े numpy सरणियों के लिए हम सामान्य रूप से [,] वाक्य रचना नहीं बल्कि [] [] से अंतिम [6 * मैं + K] [6 * j + l] अंतिम उपयोग करने के साथ शुरू करेंगे [6 * मैं + K, 6 * j + l]

दूसरों हम अक्सर आकृति बदलें और टुकड़ा करने की क्रिया जैसी चीजों का उपयोग से बनाया गया है, ताकि हम फिर उन्हें एक साथ जोड़ सकते हैं ब्लॉकों के रूप में के बजाय पुनरावृत्ति छोरों

के साथ नए सरणियों के लिए एक साधारण उदाहरण के लिए, लगातार मतभेद लेने के लिए:

y = x[1:] - x[:-1] 

शीर्षक के बारे में, 'मैट्रिक्स सृजन' स्पष्ट है। 'लोड' में फ़ाइल से डेटा पढ़ने की अधिक समझ है, जैसा कि np.loadtxt में है।

=================

N=1 साथ

तो,

In [171]: A=np.arange(0,9).reshape(3,3) 
In [172]: B=np.arange(10,19).reshape(3,3) 
In [173]: C=np.arange(20,29).reshape(3,3) 
In [174]: D=np.arange(30,39).reshape(3,3) 

In [178]: final 
Out[178]: 
array([[ 0, 1, 2, 30, 31, 32], 
     [ 3, 4, 5, 33, 34, 35], 
     [ 6, 7, 8, 36, 37, 38], 
     [20, 21, 22, 10, 11, 12], 
     [23, 24, 25, 13, 14, 15], 
     [26, 27, 28, 16, 17, 18]]) 

कौन सा कॉल के साथ बनाया जा सकता है bmat रहे हैं:

In [183]: np.bmat([[A,D],[C,B]]).A 
Out[183]: 
array([[ 0, 1, 2, 30, 31, 32], 
     [ 3, 4, 5, 33, 34, 35], 
     [ 6, 7, 8, 36, 37, 38], 
     [20, 21, 22, 10, 11, 12], 
     [23, 24, 25, 13, 14, 15], 
     [26, 27, 28, 16, 17, 18]]) 

bmathstack और vstack के मिश्रण का उपयोग करता है। यह np.matrix भी बनाता है, इसलिए .A की आवश्यकता है। @Divakar's समाधान तेजी से होना चाहिए।

यह एन = 3 के साथ मेल नहीं खाता है। 3x3 ब्लॉक आदेश से बाहर हैं। लेकिन सरणी को 6 डी (जैसा कि दिवाकर करता है) तक बढ़ा रहा है, और कुछ अक्षों को स्वैप कर रहा है, उप ब्लॉक को सही क्रम में रखता है।

N=3 के लिए:

In [57]: block=np.bmat([[A,D],[C,B]]) 
In [58]: b1=block.A.reshape(2,3,3,2,3,3) 
In [59]: b2=b1.transpose(1,0,2,4,3,5) 
In [60]: b3=b2.reshape(18,18) 
In [61]: np.allclose(b3,final) 
Out[61]: True 

त्वरित समय परीक्षणों में (एन = 3), मेरे दृष्टिकोण के बारे में आधे slicing_app की गति है।

जिज्ञासा के मामले में, bmat स्ट्रिंग इनपुट के साथ काम करता है: np.bmat('A,D;C,B')। ऐसा इसलिए है क्योंकि np.matrix MATLAB महसूस करने के लिए, कई साल पहले कोशिश कर रहा था।

1

फिर भी एक और तरीका है कि ऐसा करने के लिए, view_as_blocks का उपयोग कर:

from skimage.util import view_as_blocks 

def by_blocks(): 
    final = numpy.empty((6*N,6*N)) 
    a,b,c,d,f= [view_as_blocks(X,(3,3)) for X in [A,B,C,D,final]] 
    f[0::2,0::2]=a 
    f[1::2,1::2]=b 
    f[1::2,0::2]=c 
    f[0::2,1::2]=d 
    return final 

आपको बस ब्लॉक द्वारा ब्लॉक करना है, view_as_blocks आपके लिए strides और आकार प्रबंधित करने देता है। यह अन्य numpy समाधान के रूप में तेजी से है।

संबंधित मुद्दे