2010-07-14 6 views
39

मान लीजिए कि मेरे पास 2 डी स्पैस सरणी है। मेरा असली USECASE में दोनों पंक्तियों और स्तंभों की संख्या बहुत बड़ा कर रहे हैं (कहना 20000 और 50000) इसलिए यह स्मृति में फिट नहीं कर सकते जब एक घने प्रतिनिधित्व प्रयोग किया जाता है:ब्रॉडकास्ट घन 1 डी सरणी द्वारा acipy.sparse मैट्रिक्स को multwisely कैसे करें?

>>> import numpy as np 
>>> import scipy.sparse as ssp 

>>> a = ssp.lil_matrix((5, 3)) 
>>> a[1, 2] = -1 
>>> a[4, 1] = 2 
>>> a.todense() 
matrix([[ 0., 0., 0.], 
     [ 0., 0., -1.], 
     [ 0., 0., 0.], 
     [ 0., 0., 0.], 
     [ 0., 2., 0.]]) 

अब मान लीजिए कि मैं सभी के साथ एक घने 1 दिन सरणी है (मेरे वास्तविक जीवन के मामले में या 50000) का आकार 3 के साथ गैर शून्य घटकों:

>>> d = np.ones(3) * 3 
>>> d 
array([ 3., 3., 3.]) 

मैं एक की elementwise गुणा गणना करने के लिए पसंद है और numpy के सामान्य प्रसारण अर्थ विज्ञान का उपयोग कर d होगा। हालांकि, scipy में विरल मैट्रिक्स np.matrix के होते हैं: '*' ऑपरेटर यह एक मैट्रिक्स गुणा के बजाय की तरह व्यवहार करने के लिए ओवरलोड हो गया है elementwise-गुणा:

>>> a * d 
array([ 0., -3., 0., 0., 6.]) 

एक समाधान बनाने के लिए 'होगा * एक 'के लिए सरणी अर्थ विज्ञान के लिए स्विच' 'ऑपरेटर, कि अपेक्षित परिणाम देना होगा:

>>> a.toarray() * d 
array([[ 0., 0., 0.], 
     [ 0., 0., -3.], 
     [ 0., 0., 0.], 
     [ 0., 0., 0.], 
     [ 0., 6., 0.]]) 

लेकिन मैं ऐसा नहीं कर सकते कि जब कॉल toArray करने के लिए() के घने संस्करण अमल में लाना होगा' एक 'जो स्मृति में फिट नहीं है (और नतीजा भी घना होगा):

>>> ssp.issparse(a.toarray()) 
False 

कोई विचार यह है कि इसे केवल एक छोटे से डेटास्ट्रक्चर रखने के दौरान और 'ए' के ​​कॉलम पर एक अक्षम पाइथन लूप करने के बिना इसे कैसे बनाया जाए?

+0

तो 'd' के रूप में' आप उपयोग कर सकते A' 'a.multiply (घ)' एक ही आकार के एक विरल मैट्रिक्स है। शायद आप एक समय में 'ए' की एन पंक्तियों पर एन 'पंक्तियां बना सकते हैं और लूप कर सकते हैं? – mtrw

+1

लेकिन डी घना है और गुणा आकार आवश्यकताओं को पूरा करने के लिए स्मृति में स्पष्ट रूप से प्रसारित नहीं किया जा सकता है। बैच पर लूपिंग एक विकल्प है लेकिन मुझे यह थोड़ा सा हैक लगता है। मैंने सोचा होगा कि एक पाइथन लूप के बिना ऐसा करने के लिए एक वेनिला वेक्टरिज्ड/स्पीसी तरीका था। – ogrisel

+0

मुझे लगता है कि समस्या यह है कि आप एक (स्पैस) मैट्रिक्स का प्रतिनिधित्व करना चाहते हैं लेकिन एक सरणी के mulitply ऑपरेशन। मुझे लगता है कि आपको दुर्भाग्य से अपना खुद का रोल करना होगा। – mtrw

उत्तर

42

मैंने scipy.org पर भी उत्तर दिया, लेकिन मैंने सोचा कि मुझे यहां एक जवाब जोड़ना चाहिए, अगर अन्य लोग खोज करते समय यह पृष्ठ ढूंढें।

आप वेक्टर को एक स्पैस डायगोनल मैट्रिक्स में बदल सकते हैं और फिर प्रसारण के समान काम करने के लिए मैट्रिक्स गुणा (* के साथ) का उपयोग कर सकते हैं, लेकिन कुशलतापूर्वक।

>>> d = ssp.lil_matrix((3,3)) 
>>> d.setdiag(np.ones(3)*3) 
>>> a*d 
<5x3 sparse matrix of type '<type 'numpy.float64'>' 
with 2 stored elements in Compressed Sparse Row format> 
>>> (a*d).todense() 
matrix([[ 0., 0., 0.], 
     [ 0., 0., -3.], 
     [ 0., 0., 0.], 
     [ 0., 0., 0.], 
     [ 0., 6., 0.]]) 

आशा है कि मदद करता है!

+0

धन्यवाद ऐसा लगता है कि यह मेरी समस्या का समाधान करेगा। – ogrisel

+0

इस बारे में बड़ी बात यह है कि यह तब भी काम करता है जब 'एक्स'' ndarray' या घने मैट्रिक्स होता है। +1। –

+4

इसे ['scipy.sparse.diags (डी, 0)'] (http://docs.scipy.org/doc/scipy-0.16.1/reference/generated/scipy.sparse.diags का उपयोग करके और सरल बनाया जा सकता है। एचटीएमएल) 'lil_matrix' –

1

अच्छा, यहां एक साधारण कोड है जो आप चाहते हैं कि करेंगे। अगर यह के रूप में कुशल आप चाहते हैं के रूप में है पता नहीं है, इसलिए इसे लेने के लिए या इसे छोड़:

import scipy.sparse as ssp 
def pointmult(a,b): 
    x = a.copy() 
    for i in xrange(a.shape[0]): 
     if x.data[i]: 
      for j in xrange(len(x.data[i])): 
       x.data[i] *= b[x.rows[i]] 
    return x 

यह केवल लील मैट्रिक्स के साथ काम करता है ताकि आप कुछ परिवर्तन करने की अगर आप इसे काम करना चाहता हूँ होगा अन्य प्रारूपों के साथ।

+0

धन्यवाद, हालांकि मुझे पाइथन में लूप के लिए बचाना अच्छा लगेगा।लेकिन शायद इस उपयोग के मामले के लिए मौजूदा scipy.sparse कक्षाओं के साथ कोई रास्ता नहीं है। – ogrisel

23

मुझे लगता है कि एमुल्टिपली (बी) को तेज स्पैस में काम करना चाहिए। विधि गुणा करता है "पॉइंट-वार" गुणा करता है, मैट्रिक्स गुणा नहीं।

HTH

+1

के बजाय परिणाम एक घना मैट्रिक्स है। अच्छा नही। –

+3

@ के 3 --- आरएनसी परिणाम केवल घना है अगर बी घना है। यदि आप किसी भी स्पैर प्रारूप में बी को रूपांतरित करते हैं, तो यह चाल करेगा। जैसे A.multiply (csc_matrix (बी)) – markhor

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