2016-02-02 7 views
5

में इलिप्सिस प्रसारण आयाम पर सारांश, numpy में, मेरे पास एक सरणी है जो 2-डी या 3-डी हो सकती है, और मैं इसे प्रत्येक तत्व को स्क्वायर करते समय 2-डी तक कम करना चाहता हूं। तो मैं इस कोशिश की और यह काम नहीं करता:numpy.einsum

A = np.random.rand(5, 3, 3) 
np.einsum('...ij,...ij->ij', A, A) 

यह इस त्रुटि देता है:

ValueError: output has more dimensions than subscripts given in einstein sum, but no '...' ellipsis provided to broadcast the extra dimensions. 

मुझे लगता है einsum स्वीकार नही करता जब अंडाकार दाहिने हाथ की ओर में चला जाता है कि, मैं यदि वे मौजूद हैं, तो इलिप्सिस आयाम (ओं) पर योग करना चाहते हैं। 2-डी के लिए

A = np.random.rand(5, 3, 3) 
np.einsum('aij,aij->ij', A, A) 

और इस: वहाँ कुछ "सुंदर" जिस तरह से यह बताने के लिए है कि मैं 3 डी के लिए ऐसा करना चाहते हैं (अर्थात आयाम की संख्या जाँच और एक अगर बयान का उपयोग किए बिना) है?

A = np.random.rand(3, 3) 
np.einsum('ij,ij->ij', A, A) 

उत्तर

3

कभी कभी 'सुंदर' जिस तरह से चर आयाम को संभालने के लिए if परीक्षण का एक सेट का उपयोग करने, और उन्हें एक समारोह कॉल में छिपा है। उदाहरण के लिए np.atleast_3d पर देखें; यदि यह/4 खंड है तो यह 4W है। मैं इसे यहां अनुशंसा करता हूं, सिवाय इसके कि यह अंत में अतिरिक्त आयाम जोड़ता है, शुरुआत में नहीं। ifreshape का उपयोग कर क्लॉज महंगे (समय के अनुसार) नहीं हैं, इसलिए उनका उपयोग करने से डरो मत। भले ही आपको कुछ जादुई फ़ंक्शन मिल जाए, फिर भी उसका कोड देखें; आप आश्चर्यचकित हो सकते हैं कि क्या छिपा हुआ है।


इलिप्सिस उन आयामों के लिए उपयोग किया जाता है जो 'सवारी के लिए साथ जाते हैं', न कि जहां आप विशिष्ट नियंत्रण चाहते हैं। यहाँ आप प्रारंभिक आयाम के आधार पर योग करने के लिए चाहते हैं, तो आप स्पष्ट रूप से यह सूचकांक की जरूरत है:

In [161]: np.einsum('i...,i...',A,A) 
Out[161]: 
array([[ 1.26942035, 1.32052776, 1.74118617], 
     [ 1.59679765, 1.49331565, 2.04573002], 
     [ 2.29027005, 1.48351522, 1.36679208]]) 
In [162]: np.einsum('aij,aij->ij',A,A) 
Out[162]: 
array([[ 1.26942035, 1.32052776, 1.74118617], 
     [ 1.59679765, 1.49331565, 2.04573002], 
     [ 2.29027005, 1.48351522, 1.36679208]]) 

2 डी सरणी के लिए:

In [165]: np.einsum('ij,ij->ij',A[0],A[0]) 
Out[165]: 
array([[ 0.20497776, 0.11632197, 0.65396968], 
     [ 0.0529767 , 0.24723351, 0.27559647], 
     [ 0.62806525, 0.33081124, 0.57070406]]) 
In [166]: A[0]*A[0] 
Out[166]: 
array([[ 0.20497776, 0.11632197, 0.65396968], 
     [ 0.0529767 , 0.24723351, 0.27559647], 
     [ 0.62806525, 0.33081124, 0.57070406]]) 
In [167]: 
In [167]: np.einsum('...,...',A[0],A[0]) 
Out[167]: 
array([[ 0.20497776, 0.11632197, 0.65396968], 
     [ 0.0529767 , 0.24723351, 0.27559647], 
     [ 0.62806525, 0.33081124, 0.57070406]]) 

मुझे नहीं लगता कि आप एक अभिव्यक्ति के साथ दोनों ही मामलों को संभाल कर सकते हैं।

एक और तरीका है पहले योग

In [168]: (A*A).sum(axis=0) 
Out[168]: 
array([[ 1.26942035, 1.32052776, 1.74118617], 
     [ 1.59679765, 1.49331565, 2.04573002], 
     [ 2.29027005, 1.48351522, 1.36679208]]) 

पाने के लिए मैं पैच कि अंडाकार की हैंडलिंग तय योगदान दिया है, लेकिन यह है कि कुछ साल पहले हुआ था। तो विवरण मेरे दिमाग में सुपर ताजा नहीं हैं। उस हिस्से के रूप में मैंने स्ट्रिंग अभिव्यक्ति को पार्सिंग (मूल संकलित किया गया) को पीछे छोड़ दिया है, और यदि हमें एक और अधिक निश्चित उत्तर की आवश्यकता है, तो उस कोड की समीक्षा कर सकते हैं (या आपको इसका संदर्भ लें)।


In [172]: np.einsum('...ij,...ij->ij',A,A) 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-172-dfe39e268402> in <module>() 
----> 1 np.einsum('...ij,...ij->ij',A,A) 

ValueError: output has more dimensions than subscripts given in 
einstein sum, but no '...' ellipsis provided to broadcast 
the extra dimensions. 
In [173]: np.einsum('...ij,...ij->...ij',A,A).shape 
Out[173]: (5, 3, 3) 

त्रुटि संदेश दर्शाता है कि यह उत्पादन के लिए ... आयाम पारित करने के लिए कोशिश कर रहा है, और नहीं कर सकते हैं - क्योंकि उत्पादन आयाम या ... याद आ रही है। दूसरे शब्दों में, यह ... आयामों पर सारांश नहीं करता है। वे अपरिवर्तित आउटपुट तक पहुंच जाते हैं (प्रसारण नियम लागू होते हैं)।

+0

धन्यवाद, मैं सिर्फ एक कथन का उपयोग करने की योजना बना रहा हूं, मैं इस मामले के बारे में सिर्फ उत्सुक था क्योंकि ईन्सम फ़ंक्शन काफी दिलचस्प है कि यह सरणी संचालन करने का एक घोषणात्मक तरीका है, और यह कई अन्य सरणी में मौजूद नहीं है पुस्तकालयों/भाषाओं। मैंने पाया कि आपने कुछ समय पहले इस मामले को लाया था जब आप https://github.com/numpy/numpy/issues/2455 (बिंदु 2) में रिवर्स-इंजीनियरिंग ईन्सम थे। मुझे आश्चर्य है कि इस मामले को संभालने के लिए इन्सुम को विस्तारित करने में कितना ब्याज होगा, उदाहरण के लिए, उदाहरण के लिए, लेबल के साथ वैकल्पिक आयाम जिन्हें सारांशित किया जा सकता है।हालांकि अनुकूलित करने के लिए शायद मुश्किल है। – firescape