2015-08-23 3 views
22

मैं एक तीसरे आयाम में एक numpy 2D सरणी कॉपी करना चाहता हूं। उदाहरण के लिए, अगर मैं इस तरह के एक (2 डी) numpy सरणी था:3 डी सरणी को 3 आयाम में कॉपी करें, एन टाइम्स (पायथन)

import numpy as np 
arr = np.array([[1,2],[1,2]]) 

एन ऐसी प्रतियों के साथ एक 3 डी मैट्रिक्स में परिवर्तित एक नया आयाम में, एन के लिए इस तरह = 3:

np.array([[[1,2],[1,2]],[[1,2],[1,2]],[[1,2],[1,2]]]) 

उत्तर

34

a = np.array([[1, 2], [1, 2]]) 
print(a.shape) 
# (2, 2) 

# indexing with np.newaxis inserts a new 3rd dimension, which we then repeat the 
# array along, (you can achieve the same effect by indexing with None, see below) 
b = np.repeat(a[:, :, np.newaxis], 3, axis=2) 

print(b.shape) 
# (2, 2, 3) 

print(b[:, :, 0]) 
# [[1 2] 
# [1 2]] 

print(b[:, :, 1]) 
# [[1 2] 
# [1 2]] 

print(b[:, :, 2]) 
# [[1 2] 
# [1 2]] 

कहा करने के बाद कि, आप अक्सर अपने सरणियों दोहराने से बचें कर सकते हैं: शायद स्पष्ट तरीका np.repeat उपयोग करने के लिए है broadcasting का उपयोग करके पूरी तरह से।

c = np.array([1, 2, 3]) 

a रहे हैं: उदाहरण के लिए, मान लीजिए कि मैं एक (3,) वेक्टर जोड़ना चाहते थे करते हैं। मैं तीसरे आयाम में a 3 बार की सामग्री की प्रतिलिपि बना सकता हूं, फिर पहले और दूसरे आयामों में c की सामग्री दो बार कॉपी कर सकता हूं, ताकि मेरे दोनों सरणी (2, 2, 3) थे, फिर उनकी राशि की गणना करें। *

d = a[..., None] + c[None, None, :] 

यहाँ, a[..., None] आकार (2, 2, 1) है और c[None, None, :] आकार (1, 1, 3) है: हालांकि, यह ऐसा करने के लिए बहुत सरल और तेज है। मैं योग की गणना करते हैं, तो परिणाम 'का प्रसारण', हो जाता है आकार 1 के आयामों के साथ बाहर मुझे आकार (2, 2, 3) का एक परिणाम दे रही है:

print(d.shape) 
# (2, 2, 3) 

print(d[..., 0]) # a + c[0] 
# [[2 3] 
# [2 3]] 

print(d[..., 1]) # a + c[1] 
# [[3 4] 
# [3 4]] 

print(d[..., 2]) # a + c[2] 
# [[4 5] 
# [4 5]] 

प्रसारण एक बहुत शक्तिशाली तकनीक है, क्योंकि यह अतिरिक्त बनाने में शामिल भूमि के ऊपर से बचा जाता है स्मृति में आपके इनपुट सरणी की दोहराई गई प्रतियां।


* हालांकि मैं उन्हें स्पष्टता के लिए शामिल है, c में None सूचकांक वास्तव में आवश्यक नहीं हैं - आप भी a[..., None] + c, यानि कि कर सकता है एक (3,) सरणी के खिलाफ एक (2, 2, 1) सरणी प्रसारण करते हैं। ऐसा इसलिए है क्योंकि अगर किसी एक सरणी में दूसरे की तुलना में कम आयाम होते हैं तो केवल पीछे दो सरणी के आयामों को संगत होने की आवश्यकता होती है। एक और अधिक जटिल उदाहरण के लिए:

a = np.ones((6, 1, 4, 3, 1)) # 6 x 1 x 4 x 3 x 1 
b = np.ones((5, 1, 3, 2))  #  5 x 1 x 3 x 2 
result = a + b    # 6 x 5 x 4 x 3 x 2 
+0

कि यह वास्तव में सही परिणाम देता है सत्यापित करने के लिए पैदा करता है, तो आप भी प्रिंट कर सकते हैं 'ख [:,:, 0] ',' बी [:,:, 1] ', और' बी [:,:, 2] '। प्रत्येक तीसरा आयाम टुकड़ा मूल 2 डी सरणी की एक प्रति है। यह सिर्फ प्रिंट (बी) 'को देखकर स्पष्ट नहीं है। – ely

+0

यह एक अच्छा जवाब है !! धन्यवाद! – drg

11

एक और तरीका है numpy.dstack उपयोग करने के लिए है। मान है कि आप मैट्रिक्स anum_repeats बार दोहराना चाहते हैं:

import numpy as np 
b = np.dstack([a]*num_repeats) 

चाल एक भी तत्व की एक सूची में मैट्रिक्स a रैप करने के लिए, तो * ऑपरेटर का उपयोग num_repeats बार इस सूची में तत्वों डुप्लिकेट करने के लिए है।

उदाहरण के लिए, यदि:

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

यह तीसरा आयाम में [1 2; 1 2] 5 बार की सरणी को दोहराता है।अंत में

In [110]: import numpy as np 

In [111]: num_repeats = 5 

In [112]: a = np.array([[1, 2], [1, 2]]) 

In [113]: b = np.dstack([a]*num_repeats) 

In [114]: b[:,:,0] 
Out[114]: 
array([[1, 2], 
     [1, 2]]) 

In [115]: b[:,:,1] 
Out[115]: 
array([[1, 2], 
     [1, 2]]) 

In [116]: b[:,:,2] 
Out[116]: 
array([[1, 2], 
     [1, 2]]) 

In [117]: b[:,:,3] 
Out[117]: 
array([[1, 2], 
     [1, 2]]) 

In [118]: b[:,:,4] 
Out[118]: 
array([[1, 2], 
     [1, 2]]) 

In [119]: b.shape 
Out[119]: (2, 2, 5) 

हम देख सकते हैं कि मैट्रिक्स के आकार 2 x 2 है, तीसरे आयाम में 5 स्लाइस के साथ: (IPython में) सत्यापित करने के लिए।

+0

यह 'reshape' से तुलना कैसे करता है? और तेज? एक ही संरचना देता है? यह निश्चित रूप से साफ है। –

+0

@AnderBiguri मैंने कभी बेंचमार्क नहीं किया है ... मैंने इसे यहां मुख्य रूप से पूर्णता के लिए रखा है। यह समय के लिए दिलचस्प होगा और अंतर देखेंगे। – rayryeng

+1

मैंने अभी img = np.dstack ([arr] * 3 किया) और ठीक काम किया! धन्यवाद –

2
A=np.array([[1,2],[3,4]]) 
B=np.asarray([A]*N) 

संपादित @ Mr.F, आयाम क्रम बनाए रखने के:

B=B.T 
+0

यह मेरे लिए एक एन एक्स 2 एक्स 2 सरणी में परिणाम देता है, उदा। 'बीएचपी' प्रिंट '(एन, 2, 2)' 'एन' के मूल्य के लिए। यदि आप 'बी' के साथ 'बी' को स्थानांतरित करते हैं तो यह अपेक्षित आउटपुट से मेल खाता है। – ely

+0

@ श्री एफ - आप सही हैं। यह पहले आयाम के साथ प्रसारित होगा, और इसलिए 'बी [0], बी [1], ...' आपको सही टुकड़ा देगा, जिसे मैं तर्क दूंगा और कहूंगा कि 'बी' का उपयोग करने के बजाय टाइप करना अधिक आसान है [:,:, 0], बी [:,:, 1] ', आदि – rayryeng

+0

टाइप करना आसान हो सकता है, लेकिन उदाहरण के लिए यदि आप छवि डेटा के साथ ऐसा कर रहे हैं तो यह काफी हद तक गलत होगा, क्योंकि लगभग सभी एल्गोरिदम पिक्सेल चैनलों के 2 डी स्लाइस के लिए रैखिक बीजगणित के सम्मेलनों का उपयोग करने की अपेक्षा करें। एक ऐसे अनुप्रयोगों की कल्पना करना मुश्किल है जहां आप एक 2 डी सरणी से शुरू करते हैं, पंक्तियों और स्तंभों को एक निश्चित सम्मेलन के साथ इलाज करते हैं, और फिर आप एक ही अक्ष की एक नई अक्ष में विस्तार की एक प्रतिलिपि चाहते हैं, लेकिन अचानक आप चाहते हैं कि पहला अक्ष अर्थ बदल सके नया अक्ष बनें ... – ely

1

यहाँ एक प्रसारण उदाहरण वास्तव में क्या अनुरोध किया गया था है कि है।

a = np.array([[1, 2], [1, 2]]) 
a=a[:,:,None] 
b=np.array([1]*5)[None,None,:] 

फिर b*a वांछित परिणाम है और (b*a)[:,:,0]array([[1, 2],[1, 2]]) है, जो मूल a है, (b*a)[:,:,1] करता है के रूप में, आदि

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