2013-07-10 7 views
10

प्रसारित करते समय स्वचालित रूप से सरणी के आयामों का विस्तार करें Numpy सरणी प्रसारण में निम्न अभ्यास पर विचार करें।बेवकूफ, पायथन:

import numpy as np 
v = np.array([[1.0, 2.0]]).T # column array 

A2 = np.random.randn(2,10) # 2D array 
A3 = np.random.randn(2,10,10) # 3D 

v * A2 # works great 

# causes error: 
v * A3 # error 

मैं प्रसारण के लिए Numpy नियम पता है, और मैं Matlab में bsxfun कार्यक्षमता से परिचित हूँ। मैं समझता हूं कि एक (2, एन, एन) सरणी में एक (2,1) सरणी को प्रसारित करने का प्रयास क्यों विफल रहता है, और मुझे इससे पहले (2,1) सरणी (2,1,1) सरणी में दोहराएं प्रसारण के माध्यम से चला जाता है।

मेरा प्रश्न है: क्या कोई तरीका है कि पाइथन को किसी भी सरणी की आयाम को स्वचालित रूप से पैड करने के लिए कहने का कोई तरीका है, बिना किसी विशेष रूप से आवश्यक आयाम बताए?

मैं अन्यथा मैं कुछ बेवकूफ और mult_v_A = lambda v,A: v.reshape([v.size] + [1]*(A.ndim-1)) * A तरह मूर्खता से बदसूरत कर सकता है स्पष्ट रूप से जोड़ी को (2,1) बहुआयामी सरणी इसके खिलाफ प्रसारित किया जा रहा है के साथ वेक्टर नहीं करना चाहते ---। मुझे समय से पहले पता नहीं है कि "ए" सरणी 2 डी या 3 डी या एन-डी होगी।

मैटलैब की bsxfun प्रसारण कार्यक्षमता अनिवार्य रूप से आवश्यक आयामों को पैड करता है, इसलिए मुझे उम्मीद है कि मैं पाइथन में कुछ कर सकता हूं।

+4

मेरा विचार यह है कि यह एक सुविधा है और एक बग नहीं है। उदाहरण के लिए, मान लीजिए कि आपके पास 2-बाय-1 कॉलम वेक्टर 'v' था और फिर आपके पास 2-बाय-2-बाय -10' ndarray' था। क्या आप आकार '(2,1,1)' या आकार '(1,2,1)' रखने के लिए 'v' को दोबारा बदलना चाहते हैं? यदि आप केवल आयामों को पैड करते हैं, तो यह उपयोगकर्ता के लिए अस्पष्ट हो सकता है। एक स्पष्ट पुनर्विक्रय को मजबूर करना एक बेहतर सामान्य प्रक्रिया है, और यदि उपयोगकर्ता के पास एक निश्चित सम्मेलन है तो स्वचालित रूप से रीशेपिंग करने के लिए इसे एक विशेष फ़ंक्शन लिखने के लिए उपयोगकर्ता को छोड़ दें। लेकिन वैश्विक 'numpy' आयाम-पैडर बनाने के लिए अच्छा नहीं है जो आपके ऊपर एक सम्मेलन को मजबूर करता है। दुरुपयोग करना बहुत आसान होगा। – ely

+0

-1 @EMS। इस अस्पष्टता को आसानी से हल करके हल किया जाता है कि प्रसारण में पहला गैर-सिंगलटन आयाम का उपयोग किया जाएगा। पेशेवर प्रोग्रामर और एप्लाइड गणितज्ञों द्वारा उपयोग की जाने वाली प्रणालियों के लिए "इस तरह यह बेहतर है" का यह दृष्टिकोण पूरी तरह अनुचित है --- यह एक विशेषता नहीं है, यह अवैधता और complectedness के मामले में एक दोष है। –

+0

-1 @ अहमद फसीह। मैं एक लागू गणितज्ञ हूं जो हर दिन वैज्ञानिक अनुप्रयोगों के लिए पायथन कोड लिखता है, और मुझे लगता है कि पहले गैर-सिंगलटन आयाम को अपनाने का आपका प्रस्तावित सम्मेलन बहुत खराब होगा। आपके लिए एक ऐसा कार्य लिखना बेहतर होगा जो न्यूमपी डेवलपर्स के मुकाबले उस सम्मेलन को गोद लेता है, जो कि कुछ उपयोगकर्ताओं (जैसे आप) को लाभ पहुंचाता है, लेकिन कुछ अन्य उपयोगकर्ताओं (जैसे मुझे) के लिए उपयोगी नहीं होगा। – ely

उत्तर

9

यह बदसूरत है, लेकिन यह काम करेंगे :

(v.T * A3.T).T 

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

+1

यह वास्तव में @ unutbu के उत्तर का अध्ययन करने के बाद मेरे पास जो कुछ था, उससे कम बदसूरत है, जो 'np.swapaxes (v.T * np.swapaxes (ए 3,0, -1), 0, -1)' था! यह जानकर कि सभी आयामों को उलट देता है, यह बहुत साफ है। कम से कम उपयोगकर्ता इन ट्रांसपोज़ को देखेंगे और आशा करते हैं कि "ठीक है, यहां प्रसारण चल रहा है, आयामों को लाइन बनाने के लिए केवल थोड़ी सी स्पर्श के साथ, ठीक है, मैं ठीक हूं"। धन्यवाद प्रमुख –

8

NumPy प्रसारण बाईं ओर अतिरिक्त अक्ष जोड़ता है।

इसलिए यदि आप अपने सरणियों की व्यवस्था तो साझा कुल्हाड़ियों सही पर हैं और broadcastable कुल्हाड़ियों बाईं तरफ है, तो आप प्रसारण कोई समस्या नहीं के साथ उपयोग कर सकते हैं:

import numpy as np 
v = np.array([[1.0, 2.0]]) # shape (1, 2) 

A2 = np.random.randn(10,2) # shape (10, 2) 
A3 = np.random.randn(10,10,2) # shape (10, 10, 2) 

v * A2 # shape (10, 2) 

v * A3 # shape (10, 10, 2) 
+0

यह कम से कम आधा रास्ता समाधान है। मेरे आवेदन में स्थापित सम्मेलन दुर्भाग्य से है कि 'v' जैसे वैक्टर कॉलम सरणी हैं। मान लीजिए कि मैं पंक्ति एरे की अपेक्षा करने के लिए कोड (और मेरे उपयोगकर्ताओं) को पुनर्गठित नहीं करना चाहता था, मैं बहस कर रहा हूं कि एक ऐसा फ़ंक्शन जो प्रसारण को गुणा करने के लिए आयामों को स्वैप करता है, वास्तव में एक एएस और ' मेरी मूल पोस्ट में v'। –

+0

क्या कोई कारण है कि Numpy बाईं ओर आयाम जोड़ता है, लेकिन दाईं ओर नहीं? यह मनमाना लगता है लेकिन शायद स्मृति या बीजगणित से संबंधित कुछ महत्वपूर्ण तर्क हैं? –

+0

संभवत: अपने स्वयं के (उप-) प्रश्न का उत्तर दे रहा है, ऐसा इसलिए है क्योंकि ब्रॉडकास्टिंग सरणी के पीछे के आयामों से शुरू होता है और बाईं ओर काम करता है, और नियमों को पूरा होने तक आयामों को आवश्यकतानुसार जोड़ता रहता है? दिलचस्प! –

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