संख्यात्मक सरणी में पंक्तियों को हटाना


88

मेरे पास एक सरणी है जो इस तरह दिख सकती है:

ANOVAInputMatrixValuesArray = [[ 0.96488889, 0.73641667, 0.67521429, 0.592875, 
0.53172222], [ 0.78008333, 0.5938125, 0.481, 0.39883333, 0.]]

ध्यान दें कि एक पंक्ति में अंत में एक शून्य मान है। मैं किसी भी पंक्ति को हटाना चाहता हूं जिसमें एक शून्य है, जबकि किसी भी पंक्ति को सभी कोशिकाओं में गैर-शून्य मान रखते हैं।

लेकिन सरणी में हर बार आबादी होने पर अलग-अलग पंक्तियों की संख्या होगी, और शून्य हर बार अलग-अलग पंक्तियों में स्थित होगा।

मुझे निम्नलिखित पंक्ति के साथ प्रत्येक पंक्ति में गैर-शून्य तत्वों की संख्या मिलती है:

NumNonzeroElementsInRows    = (ANOVAInputMatrixValuesArray != 0).sum(1)

उपरोक्त सरणी के लिए, NumNonzeroElementsInRowsइसमें शामिल हैं: [५ ४]

पांच इंगित करते हैं कि पंक्ति 0 में सभी संभावित मान गैर-शून्य हैं, जबकि चार इंगित करते हैं कि पंक्ति 1 में संभावित मूल्यों में से एक शून्य है।

इसलिए, मैं उन पंक्तियों को खोजने और हटाने के लिए कोड की निम्न पंक्तियों का उपयोग करने का प्रयास कर रहा हूं जिनमें शून्य मान हैं।

for q in range(len(NumNonzeroElementsInRows)):
    if NumNonzeroElementsInRows[q] < NumNonzeroElementsInRows.max():
        p.delete(ANOVAInputMatrixValuesArray, q, axis=0)

लेकिन किसी कारण से, यह कोड कुछ भी करने के लिए प्रतीत नहीं होता है, भले ही बहुत सारे प्रिंट कमांड्स यह इंगित करते हैं कि सभी चर कोड को सही ढंग से ले जा रहे हैं।

बस "शून्य मान वाले किसी भी पंक्ति को हटाने" के लिए कुछ आसान तरीका होना चाहिए।

क्या कोई मुझे दिखा सकता है कि इसे पूरा करने के लिए क्या कोड लिखना है?

जवाबों:


162

सरणियों से पंक्तियों और स्तंभों को हटाने का सबसे सरल तरीका numpy.deleteविधि है।

मान लीजिए कि मेरे पास निम्नलिखित सरणी है x:

x = array([[1,2,3],
        [4,5,6],
        [7,8,9]])

पहली पंक्ति को हटाने के लिए, यह करें:

x = numpy.delete(x, (0), axis=0)

तीसरा कॉलम हटाने के लिए, यह करें:

x = numpy.delete(x,(2), axis=1)

तो आप उन पंक्तियों के सूचक पा सकते हैं जिनमें एक 0 है, उन्हें एक सूची या एक ट्यूपल में रखें और इसे फ़ंक्शन के दूसरे तर्क के रूप में पास करें।


धन्यवाद! मेरे पास एक ही समस्या थी, और मैं यह पता नहीं लगा सका कि केवल कॉलिंग numpy.delete(x, index)ने काम क्यों नहीं किया
एंटिमोनी

6
ध्यान दें कि सुपीरियर डिलीट () डॉक्स संकेत करते हैं कि "अक्सर बूलियन मास्क का उपयोग करना बेहतर होता है" क्योंकि एक नया सरणी वापस आ जाता है - एक उदाहरण उस लिंक के तहत प्रदान किया जाता है
आर्टुप्रोप

1
@arturomp लेकिन मुखौटा nondestructive है। क्या कॉल () समय / मेमोरी खपत को हटाने के लिए है?
नाथन

13

यहाँ एक लाइनर है (हाँ, यह user333700 के समान है, लेकिन थोड़ा और सीधा है):

>>> import numpy as np
>>> arr = np.array([[ 0.96488889, 0.73641667, 0.67521429, 0.592875, 0.53172222], 
                [ 0.78008333, 0.5938125, 0.481, 0.39883333, 0.]])
>>> print arr[arr.all(1)]
array([[ 0.96488889,  0.73641667,  0.67521429,  0.592875  ,  0.53172222]])

वैसे, यह विधि बहुत अधिक है, बड़े मैट्रिस के लिए नकाबपोश सरणी विधि की तुलना में बहुत तेज है। 2048 x 5 मैट्रिक्स के लिए, यह विधि लगभग 1000x तेज है।

वैसे, मेरे परीक्षणों में user333700 का तरीका (उनकी टिप्पणी से) थोड़ा तेज था, हालांकि यह मेरे दिमाग को चकरा देता है कि क्यों।


3
"कोई भी" शॉर्ट-सर्किट कर सकता है, जैसे ही पहले सच्चे मामले का पता चलता है, यह रुक सकता है, जबकि "सभी" को सभी शर्तों की जांच करनी होगी। तो, नहीं ("~" numpy में) किसी भी, सामान्य रूप से सभी की तुलना में तेज होना चाहिए।
जोसेफ

4
@ user333700, दोनों अलग-अलग चीजों के लिए, शॉर्ट-सर्किट कर सकते हैं। anyशॉर्ट-सर्किट का पता चला पहले सच्चे मामले में सच करने के लिए; allपहले झूठे मामले में झूठे शॉर्ट-सर्किट का पता चला। इस मामले में, शॉर्ट-सर्कुलेटिंग एक ड्रॉ होना चाहिए, लेकिन अतिरिक्त नहीं करने से यह मेरी राय में धीमा हो जाना चाहिए।
जस्टिन पील

5

यह आपके मूल दृष्टिकोण के समान है, और unutbu के उत्तर की तुलना में कम जगह का उपयोग करेगा , लेकिन मुझे संदेह है कि यह धीमा होगा।

>>> import numpy as np
>>> p = np.array([[1.5, 0], [1.4,1.5], [1.6, 0], [1.7, 1.8]])
>>> p
array([[ 1.5,  0. ],
       [ 1.4,  1.5],
       [ 1.6,  0. ],
       [ 1.7,  1.8]])
>>> nz = (p == 0).sum(1)
>>> q = p[nz == 0, :]
>>> q
array([[ 1.4,  1.5],
       [ 1.7,  1.8]])

वैसे, आपकी लाइन p.delete()मेरे लिए काम नहीं करती है - ndarrayएक .deleteविशेषता नहीं है ।


8
थोड़ा सरल: p [~ (p == 0) .any (1)] या पंक्तियों के लिए अधिक स्पष्ट: p [~ (p == 0) .any (1):]
जोसेफ

2

numpy एक ही कार्य करने के लिए एक सरल कार्य प्रदान करता है: मान लें कि आपके पास एक नकाबपोश सरणी है 'a', numpy.ma.compress_rows (a) को कॉल करने से नकाबपोश मान वाली पंक्तियों को हटा दिया जाएगा। मुझे लगता है कि यह इस तरह से बहुत तेज है ...


1
import numpy as np 
arr = np.array([[ 0.96488889, 0.73641667, 0.67521429, 0.592875, 0.53172222],[ 0.78008333, 0.5938125, 0.481, 0.39883333, 0.]])
print(arr[np.where(arr != 0.)])

-1

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

indx = []
for i in range(len(ANOVA)):
    if int(ANOVA[i,4]) == int(0):
        indx.append(i)

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