पायथन में एक सुन्न नादारे में गैर-NaN तत्वों की संख्या की गिनती


87

मुझे गैर-एनएन तत्वों की संख्या की गणना एक सुस्पष्ट ndarray मैट्रिक्स में करने की आवश्यकता है। पायथन में यह कैसे कुशलतापूर्वक होगा? इसे प्राप्त करने के लिए यहां मेरा सरल कोड है:

import numpy as np

def numberOfNonNans(data):
    count = 0
    for i in data:
        if not np.isnan(i):
            count += 1
    return count 

क्या सुपीरियर में इसके लिए कोई अंतर्निहित कार्य है? दक्षता महत्वपूर्ण है क्योंकि मैं बिग डेटा विश्लेषण कर रहा हूं।

किसी भी मदद के लिए thnx!


2
यह प्रश्न ऑफ़-टॉपिक प्रतीत होता है क्योंकि यह codereview.stackexchange.com
jonrsharpe

1
आप स्मृति के मामले में कुशल हैं?
अश्विनी चौधरी

+1 मैं CPU समय के बारे में सोच रहा था, लेकिन हाँ क्यों नहीं स्मृति भी। तेजी से और सस्ता बेहतर =)
जजाप्सुमी

3
@jjepsuomi एक मेमोरी कुशल संस्करण wil हो सकता है sum(not np.isnan(x) for x in a), लेकिन गति के मामले में यह @ M4rtini संख्यात्मक संस्करण की तुलना में धीमा है।
अश्विनी चौधरी

@ अश्विनीचौधरी आपका बहुत बहुत धन्यवाद! मुझे यह देखने की ज़रूरत है कि मेरे आवेदन में कौन सा अधिक महत्वपूर्ण है =)
जजप्सुओमी

जवाबों:


161
np.count_nonzero(~np.isnan(data))

~बूलियन मैट्रिक्स को निष्क्रिय कर देता है np.isnan

np.count_nonzeroउन मानों को गिनता है जो 0 \ false नहीं हैं। .sumएक ही परिणाम देना चाहिए। लेकिन शायद अधिक स्पष्ट रूप से उपयोग करने के लिएcount_nonzero

परीक्षण की गति:

In [23]: data = np.random.random((10000,10000))

In [24]: data[[np.random.random_integers(0,10000, 100)],:][:, [np.random.random_integers(0,99, 100)]] = np.nan

In [25]: %timeit data.size - np.count_nonzero(np.isnan(data))
1 loops, best of 3: 309 ms per loop

In [26]: %timeit np.count_nonzero(~np.isnan(data))
1 loops, best of 3: 345 ms per loop

In [27]: %timeit data.size - np.isnan(data).sum()
1 loops, best of 3: 339 ms per loop

data.size - np.count_nonzero(np.isnan(data))लगता है यहाँ मुश्किल से सबसे तेज हो। अन्य डेटा अलग सापेक्ष गति परिणाम दे सकते हैं।


+1 @ M4rtini फिर से धन्यवाद! तुम महान हो! ; डीआई जैसे ही मैं आपका जवाब स्वीकार करूंगा :)
jjepsuomi

3
शायद भी numpy.isnan(array).sum()? मैं हालांकि बहुत खाँसी के साथ कुशल नहीं हूँ।
msvalkon

2
@msvalkon, यह NaN की संख्या की गणना करेगा, जबकि OP गैर-NaN तत्वों की संख्या चाहता है।
falsetru


5
@Msvalkon उत्तर का विस्तार: data.size - np.isnan(data).sum()थोड़ा अधिक कुशल होगा।
डैनियल

10

जल्दी-जल्दी लिखने वाला

हालांकि सबसे तेज़ विकल्प नहीं है, अगर प्रदर्शन एक ऐसा मुद्दा नहीं है जिसका आप उपयोग कर सकते हैं:

sum(~np.isnan(data))

प्रदर्शन:

In [7]: %timeit data.size - np.count_nonzero(np.isnan(data))
10 loops, best of 3: 67.5 ms per loop

In [8]: %timeit sum(~np.isnan(data))
10 loops, best of 3: 154 ms per loop

In [9]: %timeit np.sum(~np.isnan(data))
10 loops, best of 3: 140 ms per loop

यह उत्तर उस राशि को प्रदान करता है जो तत्वों की संख्या की गिनती के समान नहीं है ... आपको lenइसके बजाय उपयोग करना चाहिए ।
BenT

@ बूल सरणी तत्वों का योग, जो एक निश्चित स्थिति को पूरा करता है, एक उपसमुच्चय सरणी के लेन को प्रदान करता है जो तत्वों के साथ एक निश्चित स्थिति को पूरा करता है। क्या आप स्पष्ट कर सकते हैं कि यह कहां गलत है?
जीएम

1
मेरी गलती से मैं एक बुलियन को भूल गया।
बेन मार्ट

3

यह निर्धारित करने के लिए कि सरणी विरल है, यह नैन मूल्यों का अनुपात प्राप्त करने में मदद कर सकता है

np.isnan(ndarr).sum() / ndarr.size

यदि वह अनुपात एक सीमा से अधिक है, तो एक विरल सरणी का उपयोग करें, जैसे - https://sparse.pydata.org/en/latest/


2

एक विकल्प, लेकिन थोड़ा धीमा विकल्प इसे अनुक्रमण के ऊपर करना है।

np.isnan(data)[np.isnan(data) == False].size

In [30]: %timeit np.isnan(data)[np.isnan(data) == False].size
1 loops, best of 3: 498 ms per loop 

np.isnan(data)और ==ऑपरेटर का दोहरा उपयोग थोड़ा अधिक हो सकता है और इसलिए मैंने केवल पूर्णता के लिए उत्तर पोस्ट किया।

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