2013-03-01 5 views
5

मेरे पास बड़े लेकिन दुर्लभ सरणी हैं और मैं उन्हें पंक्तियों को स्वैप करके पुनर्व्यवस्थित करना चाहता हूं। scipy.sparse में ऐसा करने का एक अच्छा तरीका क्या है?पंक्तियों और स्तंभों को स्वैप करके स्पैर सरणी का पुनर्व्यवस्थित करें

कुछ मुद्दों

  • मुझे लगता है कि नहीं है कि क्रमचय मेट्रिसेस, अच्छी तरह से इस कार्य के लिए उपयुक्त हैं के रूप में वे विरलता संरचना बेतरतीब ढंग से बदल पसंद है। और एक हेरफेर हमेशा सभी कॉलम या पंक्तियों को 'गुणा' करेगा, भले ही केवल कुछ स्वैप आवश्यक हों।

  • इस कार्य के लिए scipy.sparse में सबसे अच्छा स्पैस मैट्रिक्स प्रतिनिधित्व क्या है?

  • कार्यान्वयन के लिए सुझाव बहुत स्वागत है।

मैं Matlab के साथ इस टैग किया है और साथ ही, के बाद से इस सवाल का एक जवाब है कि जरूरी नहीं है scipy विशिष्ट मिल सकती है।

+0

मुझे इसे किसी विशेष कार्यान्वयन के लिए चाहिए। हालांकि, जैसा कि एक सहयोगी ने मुझे बताया, आम तौर पर, कोई स्पैर मैट्रिक्स पर क्रमपरिवर्तन नहीं करेगा। एक स्पैर मैट्रिक्स 'ए' आमतौर पर रैखिक मानचित्र' y = एक्स 'के रूप में प्रयोग किया जाता है, उदा। पुनरावृत्त हलकों में। इस प्रकार इस स्वैपिंग को 'ए' के ​​चारों ओर एक रैपर लिखकर बेहतर महसूस किया जाता है, इनपुट वेक्टर एक्स की प्रविष्टियों को स्वैप किया जाता है (यह 'ए' में कॉलम स्वैपिंग है) या 'y' की प्रविष्टियां (यह पंक्ति स्वैपिंग है)। – Jan

उत्तर

4

सीएससी प्रारूप सभी गैर-शून्य प्रविष्टियों के पंक्ति सूचकांक की एक सूची रखता है, सीएसआर प्रारूप सभी गैर-शून्य प्रविष्टियों के कॉलम इंडेक्स की एक सूची रखता है। मुझे लगता है कि आपको लगता है कि का लाभ लेने के चारों ओर बातें स्वैप करने के लिए इस प्रकार कर सकते हैं और मुझे लगता है कि यह करने के लिए कोई दुष्प्रभाव नहीं होना चाहिए:

def swap_rows(mat, a, b) : 
    mat_csc = scipy.sparse.csc_matrix(mat) 
    a_idx = np.where(mat_csc.indices == a) 
    b_idx = np.where(mat_csc.indices == b) 
    mat_csc.indices[a_idx] = b 
    mat_csc.indices[b_idx] = a 
    return mat_csc.asformat(mat.format) 

def swap_cols(mat, a, b) : 
    mat_csr = scipy.sparse.csr_matrix(mat) 
    a_idx = np.where(mat_csr.indices == a) 
    b_idx = np.where(mat_csr.indices == b) 
    mat_csr.indices[a_idx] = b 
    mat_csr.indices[b_idx] = a 
    return mat_csr.asformat(mat.format) 

अब आप कुछ इस तरह कर सकता है:

>>> mat = np.zeros((5,5)) 
>>> mat[[1, 2, 3, 3], [0, 2, 2, 4]] = 1 
>>> mat = scipy.sparse.lil_matrix(mat) 
>>> mat.todense() 
matrix([[ 0., 0., 0., 0., 0.], 
     [ 1., 0., 0., 0., 0.], 
     [ 0., 0., 1., 0., 0.], 
     [ 0., 0., 1., 0., 1.], 
     [ 0., 0., 0., 0., 0.]]) 
>>> swap_rows(mat, 1, 3) 
<5x5 sparse matrix of type '<type 'numpy.float64'>' 
    with 4 stored elements in LInked List format> 
>>> swap_rows(mat, 1, 3).todense() 
matrix([[ 0., 0., 0., 0., 0.], 
     [ 0., 0., 1., 0., 1.], 
     [ 0., 0., 1., 0., 0.], 
     [ 1., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 0.]]) 
>>> swap_cols(mat, 0, 4) 
<5x5 sparse matrix of type '<type 'numpy.float64'>' 
    with 4 stored elements in LInked List format> 
>>> swap_cols(mat, 0, 4).todense() 
matrix([[ 0., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 1.], 
     [ 0., 0., 1., 0., 0.], 
     [ 1., 0., 1., 0., 0.], 
     [ 0., 0., 0., 0., 0.]]) 

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

+0

धन्यवाद @ जैम, ऐसा लगता है कि मैं क्या देख रहा था। और यह दिखाता है कि मुझे स्पैस प्रारूपों से अधिक परिचित होना चाहिए। – Jan

+0

@ जेन आप इसे थोड़ा और परीक्षण करना चाहते हैं, मुझे लगता है कि ऊपर दिए गए उदाहरण काम करते हैं क्योंकि सभी गैर-शून्य प्रविष्टियां समान हैं। मेरे पास अभी समय नहीं है, लेकिन बाद में अधिक विस्तार से इसमें देखेंगे। एक और सरणी है, 'mat.indptr', जिसे कुछ बदलना भी आवश्यक हो सकता है। [येल स्पैस प्रारूप पर विकिपीडिया लेख] (http://en.wikipedia.org/wiki/Sparse_matrix#Yale_format) में सभी जानकारी की आवश्यकता है, यदि आप इसे स्वयंमाने की कोशिश करते हैं! – Jaime

+0

मैं इसका परीक्षण करूंगा और आपको बता दूंगा ... स्रोत के लिए धन्यवाद। – Jan

0

मैटलैब में आप सिर्फ सूचकांक स्तंभों और पंक्तियों को अपनी इच्छानुसार कर सकते हैं:

Matrix = speye(10); 
mycolumnorder = [1 2 3 4 5 6 10 9 8 7]; 
myroworder = [4 3 2 1 5 6 7 8 9 10]; 
Myorderedmatrix = Matrix(myroworder,mycolumnorder); 

मुझे लगता है कि इस विरलता को बरकरार रखता है ... के बारे में scipy हालांकि पता नहीं है ...

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