2013-07-02 5 views
6

मैं एन बाहरी उत्पादों की गणना करने के लिए एक तेज़ तरीका ढूंढ रहा हूं।पायथन - बाहरी उत्पादों को समस्त करने का तेज़ तरीका?

अनिवार्य रूप से, मैं सामान्य वितरण से उत्पन्न दो मैट्रिक्स के साथ शुरू - वी तत्वों के साथ वैक्टर n देखते हैं:

A = np.random.normal(size = (n, v)) 
B = np.random.normal(size = (n, v)) 

मैं चाहता क्या एक में आकार वी के प्रत्येक वेक्टर के बाहरी उत्पादों की गणना करने के लिए है और बी और उन्हें एक साथ जोड़ो।

ध्यान दें कि A * B.T काम नहीं करता है - ए आकार एन एक्स वी है जबकि बी आकार v x n है।

सबसे अच्छा मैं कर सकता हूं एक लूप बनाना जहां बाहरी उत्पादों का निर्माण किया गया है, फिर बाद में सम्मिलित किया गया। मैं यह इसलिए की तरह है:

outers = np.array([A[i] * B[i].T]) 

यह एक n एक्स वी एक्स वी सरणी बनाता है, जो मैं तो np.sum(outers, axis = 0) का उपयोग करके एक साथ जोड़ सकते हैं (पाश सूची समझ, जो बाद में एक सरणी में बदल जाता है के भीतर है)। हालांकि, यह काफी धीमी है, और मैं सोच रहा था कि एक वेक्टरीकृत फ़ंक्शन है जिसका उपयोग मैं इसे गति देने के लिए कर सकता था।

अगर किसी के पास कोई सलाह है, तो मैं वास्तव में इसकी सराहना करता हूं!

उत्तर

7

ऐसा लगता है कि आपको बस इतना करना है कि पारदर्शिता के क्रम को बदलना है, और के बजाय A.T * B करें।

यदि आप इसके बाद काफी कुछ नहीं कर रहे हैं, तो np.einsum पर एक नज़र डालें, जो कुछ बहुत शक्तिशाली वूडू कर सकता है। उपर्युक्त उदाहरण के लिए, आप करेंगे:

np.einsum('ij,ik->jk', A, B) 
+0

ईन्सम खूबसूरती से काम करता है। धन्यवाद! – Adam

2

np.outer पर भी विचार करें।

np.array([np.outer(A, B) for i in xrange(n)]).sum(0) 

हालांकि np.einsum @Jamie ने सुझाव दिया स्पष्ट विजेता है। , एक तरफ

In [65]: np.testing.assert_allclose(method_outer, method_einsum) 

लेकिन एक के रूप में, मैं सफलतापूर्वक नहीं मिल रहा है कि A.T * B या A * B.T प्रसारण:

In [63]: %timeit np.einsum('ij,ik->jk', A, B) 
100000 loops, best of 3: 4.61 us per loop 

In [64]: %timeit np.array([np.outer(A[i], B[i]) for i in xrange(n)]).sum(0) 
10000 loops, best of 3: 169 us per loop 

और, यह सुनिश्चित करने, उनके परिणाम समान हैं।

+0

वह 'np.matrix' ऑब्जेक्ट्स गुणा कर रहा है, न कि 'np.ndarray'। 'ए * बीटी 'तब' np.dot (ए, बीटी) ', और' एटी * बी' के बराबर 'np.dot (एटी, बी)' के बराबर है। यह बहुत करीब होना चाहिए, 'np.einsum' के बहुत करीब है। दो तरीकों के बीच अच्छी तुलना करने के लिए – Jaime

+0

+1 – elaRosca

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