एक मैट्रिक्स को सुन्न में जगह दें


27

मैं अजगर की सुन्न लाइब्रेरी का उपयोग करके, इसकी कई पंक्तियों और स्तंभों के क्रम को बदलकर एक घने वर्ग संक्रमण मैट्रिक्स को संशोधित करना चाहता हूं। गणितीय रूप से यह मैट्रिक्स को क्रमपरिवर्तन मैट्रिक्स P से पूर्व-गुणा करने और P ^ -1 = P ^ T से गुणा करने से संबंधित है, लेकिन यह एक कम्प्यूटेशनल रूप से उचित समाधान नहीं है।

अभी मैं मैन्युअल रूप से पंक्तियों और स्तंभों की अदला-बदली कर रहा हूं, लेकिन मुझे उम्मीद है कि एक अच्छा कार्य f (M, v) के लिए पर्याप्त होगा जहाँ M में n पंक्तियाँ और स्तंभ हैं, और v में n प्रविष्टियाँ हैं, ताकि f (M, v) अपडेट सूचकांक क्रमांक v के अनुसार M। हो सकता है कि मैं इंटरनेट पर खोज करने में असफल रहा हो।

ऐसा कुछ संभव हो सकता है सुपी के "उन्नत अनुक्रमण" के साथ, लेकिन मेरी समझ यह है कि ऐसा समाधान इन-प्लेस नहीं होगा। कुछ साधारण स्थितियों के लिए भी यह अलग से एक इंडेक्स परमीशन को ट्रैक करने के लिए पर्याप्त हो सकता है, लेकिन यह मेरे मामले में सुविधाजनक नहीं है।

जोड़ा गया:
कभी-कभी जब लोग क्रमपरिवर्तन के बारे में बात करते हैं, तो उनका अर्थ केवल यादृच्छिक क्रमपरिवर्तन का नमूना होता है, उदाहरण के लिए आंकड़ों में पी-मान प्राप्त करने के लिए एक प्रक्रिया के भाग के रूप में। या उनका मतलब है कि गिनती करना या सभी संभव क्रमपरिवर्तन की गणना करना। मैं इन चीजों के बारे में बात नहीं कर रहा हूं।

जोड़ा गया:
मैट्रिक्स डेस्कटॉप रैम में फिट होने के लिए काफी छोटा है लेकिन इतना बड़ा है कि मैं इसे बिना सोचे-समझे कॉपी नहीं करना चाहता। वास्तव में मैं जितना हो सके मैट्रिसेस का उपयोग करना चाहूंगा, लेकिन मैं उन्हें रैम में नहीं रखने की असुविधा से निपटना चाहता हूं, और मैं मैट्रिक्स पर O (N ^ 3) LAPACK संचालन करता हूं जो कि व्यावहारिक मैट्रिक्स आकार को सीमित करें। मैं वर्तमान में इस बड़े पैमाने पर अनावश्यक रूप से मैट्रिसेस की प्रतिलिपि बनाता हूं, लेकिन मुझे उम्मीद है कि यह क्रमचय के लिए आसानी से बचा जा सकता है।


3
यह अच्छा होगा यदि आप अपने मैट्रिसेस का आकार देने के लिए प्रश्न को अपडेट कर सकते हैं। "विशाल" का मतलब सभी लोगों के लिए समान नहीं है।
बिल बर्थ

2
आप सही हैं कि उन्नत (या तथाकथित फैंसी) अनुक्रमण एक प्रतिलिपि बनाता है। लेकिन अगर आप उस तथ्य के साथ रहना स्वीकार करते हैं तो आपका कोड सिर्फ M[v]पंक्तियों को अनुमति देना है।
डैनियल वेलकोव

@daniel: और यह एम [v::] [:, v] पूरे क्रमपरिवर्तन के लिए होगा? क्या यह फैंसी इंडेक्सिंग का उपयोग करके क्रमचय प्राप्त करने का सबसे अच्छा तरीका होगा? और क्या यह मूल मैट्रिक्स के आकार, पंक्ति + स्तंभ अनुमत मैट्रिक्स, और अस्थायी पंक्ति अनुमत मैट्रिक्स सहित 3x मैट्रिक्स मेमोरी का उपयोग करेगा?
कोई भी

यह सही है, आपके पास अपनी मूल मैट्रिक्स और 2 प्रतियां होंगी। Btw आपको एक ही समय में पंक्तियों और स्तंभों दोनों की अनुमति देने की आवश्यकता क्यों है?
डैनियल वेलकोव

4
आप अनुमति प्राप्त मैट्रिक्स के साथ क्या करने जा रहे हैं? ऑपरेटर को लागू करते समय वेक्टर को बस अनुमति देना बेहतर हो सकता है।
जेड ब्राउन

जवाबों:


9

डॉक्स के अनुसार, वहाँ numpy, की तरह कुछ में कोई यथा-स्थान क्रमचय विधि है ndarray.sort

तो आपके विकल्प हैं (यह मानते हुए कि Mएक मैट्रिक्स और क्रमपरिवर्तन वेक्टर है)N×Np

  1. एक विस्तार मॉड्यूल के रूप में सी में अपने खुद के एल्गोरिदम को लागू करना (लेकिन इन-प्लेस एल्गोरिदम कठिन हैं, कम से कम मेरे लिए!)
  2. N मेमोरी ओवरहेड

    for i in range(N):
        M[:,i] = M[p,i]
    for i in range(N):
        M[i,:] = M[i,p]
    
  3. N2 मेमोरी ओवरहेड

    M[:,:] = M[p,:]
    M[:,:] = M[:,p]
    

आशा है कि ये सबॉप्टीमल हैक उपयोगी हैं।


@ एक हैक है 2. जिसे आप 'मैन्युअल रूप से स्वैपिंग रो और कॉलम' कहते हैं?
स्टेफानो एम।

1
मैं विकल्प 1 और 2 को जोड़ूंगा: सी कोड लिखूंगा जो प्रत्येक अनुमत कॉलम को लिखने के लिए आदेश एन के एक बफर का उपयोग करता है, फिर इसे वापस लिखता है कि यह कहां से आया है; फिर पंक्तियों के लिए भी ऐसा ही करें। जैसा @Stefano लिखते हैं, यह केवल अतिरिक्त मेमोरी लेता है , जिसे आप पहले से ही क्रमपरिवर्तन को स्टोर करने के लिए खर्च कर रहे हैं । पीO(N)p
एरिक पी।

@ErikP। एक सी कार्यान्वयन अतिरिक्त मेमोरी उचित है और सुनिश्चित करें कि आपका तितर बितर लेखन और प्रतिलिपि वापस दृष्टिकोण ध्वनि है। दिलचस्प सवाल यह है कि अगर अतिरिक्त मेमोरी दी जाए तो अधिक कुशल एल्गोरिदम हैं । उत्तर कठिन है मुझे लगता है, क्योंकि हमें प्रोसेसर आर्किटेक्चर, मेमोरी एक्सेस पैटर्न, कैश हिट्स को ध्यान में रखना चाहिए ... यह कहा कि मैं आपकी सलाह का पालन करूंगा और एल्गोरिथ्म को लागू करने के लिए एक सरल और आसान के लिए जाऊंगा। O ( N )O(N)O(N)
स्टेफानो एम

2
यह एक साइथन समारोह के लिए वास्तव में अच्छा है। Shoudln't 10 से अधिक लाइनों हो। । । क्या मैं इसे एक दरार देना चाहता हूं?
मेवप्लप

जबरदस्त हंसी। मैंने इसे साइथन के लिए शुरू किया, फिर एक फ़ंक्शन में सही उत्तर मिला कि मैं हर समय उपयोग करता हूं। रवींद्र। मेरा पोस्ट किया गया जवाब देखें।
मेवोप्लप

6

चेतावनी: नीचे दिया गया उदाहरण ठीक से काम करता है, लेकिन पोस्ट के अंत में सुझाए गए मापदंडों के पूर्ण सेट का उपयोग करके बग , या numpy.take () फ़ंक्शन में कम से कम एक "अनकम्प्लेटेड सुविधा" को उजागर करता है। विवरण के लिए नीचे टिप्पणी देखें। बग रिपोर्ट दर्ज कराई

आप इसे इनपॉइज़ के टेक () फंक्शन के साथ कर सकते हैं , लेकिन इसके लिए हूप जंपिंग की आवश्यकता होती है।

यहाँ एक पहचान मैट्रिक्स की पंक्तियों के यादृच्छिक क्रमांकन करने का एक उदाहरण है:

import numpy as np
i = np.identity(10)
rr = range(10)
np.random.shuffle(rr)
np.take(i, rr, axis=0)
array([[ 0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.],
       [ 1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  1.]])

इसे इन-प्लेस करने के लिए, आपको केवल "आउट" पैरामीटर निर्दिष्ट करना होगा जो इनपुट ऐरे के समान होगा और आपको मोड = "क्लिप" या मोड = "रैप" सेट करना होगा। यदि आप मोड सेट नहीं करते हैं, तो यह एक पायथन अपवाद पर सरणी राज्य को पुनर्स्थापित करने के लिए एक प्रतिलिपि बना देगा (यहां देखें)

अंतिम नोट पर, एक सरणी विधि लगती है, इसलिए इसके बजाय

np.take(i, rr, axis=0)

आप कॉल कर सकते हैं

i.take(rr, axis=0)

यदि वह आपके स्वाद के लिए अधिक है। तो कुल मिलाकर आपको निम्नलिखित बातों पर ध्यान देना चाहिए:

#Inplace Rearrange
arr = makeMyBixMatrix()
pVec0, pVec1 = calcMyPermutationVectors()
arr.take(pVec0, axis=0, out=arr, mode="clip")
arr.take(pVec1, axis=1, out=arr, mode="clip")

दोनों पंक्तियों और स्तंभों की अनुमति देने के लिए, मुझे लगता है कि आपको या तो इसे दो बार चलाना होगा, या कुछ बदसूरत shenanigans को numpy.unravel_index के साथ खींचना होगा, जिसके बारे में सोचने के लिए मेरे सिर में दर्द होता है।


जैसा कि कहा गया है, जगह में एल्गोरिदम कठिन हैं। आपका समाधान सुन्न 1.6.2 के साथ काम नहीं करता है । और 1.7.1 (डुप्लीकेट रो / कॉलम)। अगर 1.8.x इस समस्या को ठीक करता है तो जाँच करने का कोई समय नहीं था
स्टेफानो एम

हममम। क्या आप कहीं टेस्ट कोड पोस्ट कर सकते हैं? मेरे सिर में, मुझे लगता है कि हालांकि सूचकांकों पर एक तरह का ऑपरेशन करने की आवश्यकता है जो प्लकिंग से पहले होती है। मैं इस पीएम की और जांच करूंगा।
मायवोप्लप

1
जब मैं चलाने के लिए इस कोड मैं 1.6.2, test take, not overwriting: True, test not-in-place take: True, test in-place take: False, rr [3, 7, 8, 1, 4, 5, 9, 0, 2, 6], arr [30 70 80 70 40 50 90 30 80 90], ref [30 70 80 10 40 50 90 0 20 60]। तो np.takeकम से कम सुन्न 1.6.2 के लिए एक जगह में क्रमपरिवर्तन करने के बारे में पता नहीं है और चीजों को गड़बड़ कर देता है।
स्टेफानो एम

Yeouch। अच्छा प्रदर्शन किया। यह शायद बग आईएमएचओ के रूप में योग्य है। बहुत कम से कम डॉक्स को यह कहना चाहिए कि इनपुट और आउटपुट एक ही एरे नहीं हो सकते हैं, शायद देखने के लिए जाँच करें और सिवाय इसके कि वह है।
meawoppl

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

2

यदि आपके पास एक विरल मैट्रिक्स है जो COOप्रारूप में संग्रहीत है , तो निम्नलिखित मददगार हो सकता है

    A.row = perm[A.row];
    A.col = perm[A.col];

यह सोचते हैं कि Aशामिल COOमैट्रिक्स, और permएक है numpy.arrayक्रमचय हैं। यह केवल मेमोरी ओवरहेड होगा, जहां मैट्रिक्स के गैर-शून्य तत्वों की संख्या है।मीmm


लेकिन C00ते पहले स्थान पर एक विरल मैट्रिक्स के रूप में एक पूर्ण घने मैट्रिक्स के भंडारण के लिए मेमोरी ओवरहेड क्या है?
फेडरिको पोलोनी

चूंकि तत्वों की संख्या एक विरल और पूर्ण (पूर्ण) घनी प्रतिनिधित्व दोनों में समान है, स्मृति अंतर केवल एक स्थिर (2 ints और 1 floatविरल प्रतिनिधित्व में तत्व के रूप में एक एकल floatघने प्रतिनिधित्व में) है। लेकिन इस विधि का मेमोरी ओवरहेड एक घने मामले में होगा , इसलिए संभवत: नियमित एस से बेहतर छड़ी हो सकती है । n2numpy.ndarray
विन्सेंट ट्रेग

1

मेरे पास टिप्पणी करने के लिए पर्याप्त प्रतिष्ठा नहीं है, लेकिन मुझे लगता है कि निम्नलिखित एसओ प्रश्न मददगार हो सकते हैं: /programming/4370745/view-onto-a-numpy-array

बुनियादी अंक है कि आप उपयोग कर सकते हैं बुनियादी टुकड़ा करने की क्रिया और उस कॉपी किए बिना सरणी पर एक दृश्य पैदा करेगा, लेकिन यदि आप ऐसा उन्नत टुकड़ा करने की क्रिया / अनुक्रमण तो यह होगा एक प्रतिलिपि बनाने के।


ओपी एक क्रमचय के लिए पूछ रहा है, और यह मूल टुकड़ा करने की क्रिया के साथ संभव नहीं है।
स्टेफानो एम

आप निश्चित रूप से सही हैं। मुझे लगा कि ओपी के लिए यह समझना उपयोगी होगा कि स्लाइसिंग के साथ क्या हो रहा था (यदि उन्हें पता नहीं था), क्योंकि वे इस बारे में चिंतित थे कि कॉपियाँ कब होंगी। यदि वह आपके उत्तर से कुछ उपयोग करता है, तो मुझे लगता है कि यह जानना अच्छा होगा क्योंकि आप उन्हें अपने छोरों के अंदर उपयोग करते हैं।
hadsed

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.