2012-08-26 7 views
7

मान लीजिए कि मेरे पास सीएसआर प्रारूप में एक मैट्रिक्स है, शून्य (या पंक्तियों) को शून्य पर सेट करने का सबसे प्रभावी तरीका क्या है?scipy.sparse: शून्य को पंक्ति सेट करें

निम्नलिखित कोड काफी धीमे चलता है:

A = A.tolil() 
A[indices, :] = 0 
A = A.tocsr() 

मैं scipy.sparse.lil_matrix में बदलने की वजह से सीएसआर प्रारूप न फैंसी अनुक्रमण और न ही स्लाइस के मूल्य निर्धारित करने का समर्थन करने लगता था।

+0

ठीक है, मैं बस की कोशिश की एक '[एक .__ setitem __ ((i, j), 0) मैं जे श्रेणी में जे के लिए सूचकांक में (एशप [1])] 'और' SciPy' ने मुझे बताया कि 'स्पैसएफ़िशियेंसी चेतावनी: एक csr_matrix की स्पर्सिटी संरचना को बदलना महंगा है। lil_matrix अधिक कुशल है। 0 ... –

+0

कोई विचार नहीं है कि scipy के लिए इसका कोई समर्थन है, लेकिन जैसा कि यह एक सीएसआर मैट्रिक्स है, इसे कुशलता से संभाला जा सकता है (कम से कम हाथ से)। एक सवाल यह है कि, क्या आप स्पष्टीकरण पैटर्न को बदलना चाहते हैं, या उन 0 को संख्यात्मक रूप से 0 होना चाहिए? – seberg

+0

मुझे यकीन नहीं है कि स्पष्टीकरण पैटर्न का क्या अर्थ है।मैं scipy.sparse.linalg.spsolve समारोह का उपयोग करके समीकरणों की एक प्रणाली को हल करने के लिए आगे बढ़ता हूं। मुझे उम्मीद है कि यह स्पष्टीकरण पैटर्न, या इसकी कमी को बदलने की जरूरत स्थापित करता है। –

उत्तर

5

मुझे लगता है कि SciPy बस इसे लागू नहीं है, लेकिन सीएसआर प्रारूप काफी अच्छी तरह से इस का समर्थन करेगा, कृपया "विरल मैट्रिक्स" पर विकिपीडिया लेख के बारे में पढ़ा क्या indptr, आदि कर रहे हैं:

# A.indptr is an array, one for each row (+1 for the nnz): 

def csr_row_set_nz_to_val(csr, row, value=0): 
    """Set all nonzero elements (elements currently in the sparsity pattern) 
    to the given value. Useful to set to 0 mostly. 
    """ 
    if not isinstance(csr, scipy.sparse.csr_matrix): 
     raise ValueError('Matrix given must be of CSR format.') 
    csr.data[csr.indptr[row]:csr.indptr[row+1]] = value 

# Now you can just do: 
for row in indices: 
    csr_row_set_nz_to_val(A, row, 0) 

# And to remove zeros from the sparsity pattern: 
A.eliminate_zeros() 
बेशक

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

आप निश्चित रूप से eliminate_zeros और prune के शॉर्ट-सर्किट के सिद्धांत में हो सकते हैं, लेकिन यह बहुत परेशानी होनी चाहिए, और धीमी हो सकती है (क्योंकि आप इसे सी में नहीं करेंगे)।


eliminiate_zeros (और छँटाई) के बारे में विवरण

विरल मैट्रिक्स, आम तौर पर शून्य तत्वों, लेकिन सिर्फ दुकानों को बचाने नहीं है जहां अशून्य तत्व (मोटे तौर पर और विभिन्न तरीकों के साथ) कर रहे हैं। eliminate_zeros स्पैरसिटी पैटर्न से अपने मैट्रिक्स में सभी शून्य हटा देता है (यानी उस स्थिति के लिए कोई मूल्य संग्रहीत नहीं किया जाता है, जब एक vlaue संग्रहीत था, लेकिन यह 0 था)। हटाएं यदि आप 0 को किसी भिन्न मान के बाद में बदलना चाहते हैं तो अन्यथा, यह स्थान बचाता है।

प्रून तब आवश्यक डेटा सरणी को छोटा कर देगा जब वे लंबे समय तक आवश्यक हों। ध्यान दें कि जब मेरे पास पहले A.prune() था, A.eliminiate_zeros() में पहले से ही प्रुन शामिल है।

+0

धन्यवाद! वह चीजों को काफी बढ़ाया! मैं सिर्फ यह जानना चाहता हूं कि elim_zeros और prune कथन क्या कर रहे हैं? –

+0

एक (उम्मीदपूर्वक समझने योग्य) वाक्य जोड़ा गया। ध्यान दें कि 'prune() 'अनावश्यक था,' elim_zeros' पहले ही 'prune' को कॉल करता है – seberg

0

scipy के नवीनतम संस्करण में अद्यतन करें। यह फैंसी इंडेक्सिंग का समर्थन करता है।

0

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

आप निम्न कार्यों में से एक की आवश्यकता होगी:

import scipy.sparse 

def zero_rows(M, rows): 
    diag = scipy.sparse.eye(M.shape[0]).tolil() 
    for r in rows: 
     diag[r, r] = 0 
    return diag.dot(M) 

def zero_columns(M, columns): 
    diag = scipy.sparse.eye(M.shape[1]).tolil() 
    for c in columns: 
     diag[c, c] = 0 
    return M.dot(diag) 

प्रयोग उदाहरण:

>>> A = scipy.sparse.csr_matrix([[1,0,3,4], [5,6,0,8], [9,10,11,0]]) 
>>> A 
<3x4 sparse matrix of type '<class 'numpy.int64'>' 
     with 9 stored elements in Compressed Sparse Row format> 
>>> A.toarray() 
array([[ 1, 0, 3, 4], 
     [ 5, 6, 0, 8], 
     [ 9, 10, 11, 0]], dtype=int64) 

>>> B = zero_rows(A, [1]) 
>>> B 
<3x4 sparse matrix of type '<class 'numpy.float64'>' 
     with 6 stored elements in Compressed Sparse Row format> 
>>> B.toarray() 
array([[ 1., 0., 3., 4.], 
     [ 0., 0., 0., 0.], 
     [ 9., 10., 11., 0.]]) 

>>> C = zero_columns(A, [1, 3]) 
>>> C 
<3x4 sparse matrix of type '<class 'numpy.float64'>' 
     with 5 stored elements in Compressed Sparse Row format> 
>>> C.toarray() 
array([[ 1., 0., 3., 0.], 
     [ 5., 0., 0., 0.], 
     [ 9., 0., 11., 0.]]) 
संबंधित मुद्दे