एक सरणी से नैन मूल्यों को हटाना


223

मैं यह जानना चाहता हूं कि मेरे सरणी से नैन मूल्यों को कैसे हटाया जाए। मेरी सरणी कुछ इस तरह दिखती है:

x = [1400, 1500, 1600, nan, nan, nan ,1700] #Not in this exact configuration

मैं nanमूल्यों को कैसे हटा सकता हूं x?


स्पष्ट होने के लिए, "NaNs को हटा दें" से आपका मतलब केवल गैर-शून्य मानों के सबसेट को फ़िल्टर करना है । "NaNs को कुछ मान से न भरें (शून्य, स्थिर, माध्य, माध्यिका, आदि)"
smci

जवाबों:


362

यदि आप अपने सरणियों के लिए numpy का उपयोग कर रहे हैं, तो आप भी उपयोग कर सकते हैं

x = x[numpy.logical_not(numpy.isnan(x))]

इसके तुल्य

x = x[~numpy.isnan(x)]

[जोड़ा आशुलिपि के लिए chbrown के लिए धन्यवाद]

व्याख्या

आंतरिक फ़ंक्शन, numpy.isnanएक बूलियन / तार्किक सरणी देता है जिसका मूल्य Trueहर जगह होता xहै जो संख्या नहीं है। हम विपरीत चाहते रूप में, हम तार्किक-नहीं ऑपरेटर का उपयोग, ~के साथ एक सरणी प्राप्त करने के लिए Trueहर जगह है कि रों x है एक वैध संख्या।

अंत में, हम इस तार्किक सरणी को मूल सरणी में अनुक्रमित करने के लिए उपयोग करते हैं x, केवल गैर-NaN मान प्राप्त करने के लिए।


31
याx = x[numpy.isfinite(x)]
आलसी 1

14
या x = x[~numpy.isnan(x)], जो कि म्यूटाज़ट्रॉन के मूल उत्तर के बराबर है, लेकिन छोटा है। यदि आप अपने शिशुओं को चारों ओर रखना चाहते हैं, तो यह जान लें कि numpy.isfinite(numpy.inf) == False, लेकिन ~numpy.isnan(numpy.inf) == True
chbrown

8
जो लोग इसे एक निडर के साथ हल करने और आयाम बनाए रखने के लिए देख रहे हैं, के लिए सुन्न का उपयोग करें :np.where(np.isfinite(x), x, 0)
BoltzmannBrain

1
लेखन त्रुटि: केवल पूर्णांक अदिश सरणियों एक अदिश सूचकांक में बदला जा सकता
towry

1
@towry: यह इसलिए हो रहा है क्योंकि आपका इनपुट, xएक संख्यात्मक सरणी नहीं है। यदि आप तार्किक अनुक्रमण का उपयोग करना चाहते हैं, तो यह एक सरणी होना चाहिए - उदाहरण के लिएx = np.array(x)
jmetz

50
filter(lambda v: v==v, x)

केवल vN के लिए v! = v के बाद से सूचियों और संख्या दोनों के लिए कार्य करता है


5
एक हैक लेकिन इस मामले में विशेष रूप से उपयोगी एक है जहां आप मिश्रित प्रकार के साथ वस्तुओं के एक सरणी से नैन को फ़िल्टर कर रहे हैं, जैसे कि स्ट्रिंग्स और नैन।
ऑस्टिन रिचर्डसन

बहुत साफ समाधान।
मूंदड़ा

2
यह चालाक लग सकता है, लेकिन अगर तर्क और सैद्धांतिक रूप से अन्य वस्तुओं (जैसे कस्टम कक्षाएं) को अस्पष्ट करता है, तो यह संपत्ति भी हो सकती है
क्रिस_रैंड

यह भी उपयोगी है क्योंकि इसे केवल xएक बार निर्दिष्ट करने की आवश्यकता है क्योंकि यह समाधान के प्रकार के विपरीत है x[~numpy.isnan(x)]। यह सुविधाजनक है जब xएक लंबी अभिव्यक्ति द्वारा परिभाषित किया गया है और आप इस लंबी अभिव्यक्ति के परिणाम को संग्रहीत करने के लिए एक अस्थायी चर बनाकर कोड को अव्यवस्थित नहीं करना चाहते हैं।
क्रिश्चियन ओ'रिली

34

इसे इस्तेमाल करे:

import math
print [value for value in x if not math.isnan(value)]

अधिक के लिए, सूची समझ पर पढ़ें ।


5
यदि आप मेरे दोनों उत्तर का उपयोग कर रहे हैं, और @ lazy1 सूची बोध की तुलना में तेजी से परिमाण का एक क्रम है - lazy1 का समाधान थोड़ा तेज है (हालांकि तकनीकी रूप से भी कोई अनंत मान वापस नहीं आएगा)।
जामेत्ज़

कोष्ठक मत भूलना :)print ([value for value in x if not math.isnan(value)])
हाइपर

यदि आप शीर्ष उत्तर की तरह सुन्न का उपयोग कर रहे हैं, तो आप npपैकेज के साथ इस सूची को समझने के उत्तर का उपयोग कर सकते हैं : इसलिए बिना [value for value in x if not np.isnan(value)]
nans के


6

उपरोक्त कार्य करना:

x = x[~numpy.isnan(x)]

या

x = x[numpy.logical_not(numpy.isnan(x))]

मैंने पाया कि एक ही चर (x) पर रीसेट करने से वास्तविक नैनो मान नहीं हटते हैं और एक अलग चर का उपयोग करना पड़ता है। इसे एक अलग चर में स्थापित करने से नैन्स को हटा दिया गया। जैसे

y = x[~numpy.isnan(x)]

यह अजीब है; डॉक्स के अनुसार , बूलियन एरे इंडेक्सिंग (जो कि यह है), उन्नत इंडेक्सिंग के तहत है, जो जाहिरा तौर पर "डेटा की एक प्रति लौटाता है", इसलिए आपको xनए मूल्य (यानी NaN के बिना) के साथ ओवर राइट करना चाहिए। । क्या आप ऐसा करने के लिए कोई और जानकारी प्रदान कर सकते हैं?
जामेत्ज़

5

जैसा कि दूसरों द्वारा दिखाया गया है

x[~numpy.isnan(x)]

काम करता है। लेकिन यह एक त्रुटि फेंक देगा यदि सुन्न dtype एक मूल डेटा प्रकार नहीं है, उदाहरण के लिए यदि यह ऑब्जेक्ट है। उस स्थिति में आप पांडा का उपयोग कर सकते हैं।

x[~pandas.isna(x)] or x[~pandas.isnull(x)]

4

स्वीकार किए जाते हैं जवाब 2 डी सरणियों के लिए आकार बदल जाता है। मैं पंडों की बूंद () कार्यक्षमता का उपयोग करते हुए यहां एक समाधान प्रस्तुत करता हूं । यह 1D और 2D एरेज़ के लिए काम करता है। 2 डी मामले में आप के लिए मौसम का चयन कर सकते पंक्ति या स्तंभ ड्रॉप युक्त np.nan

import pandas as pd
import numpy as np

def dropna(arr, *args, **kwarg):
    assert isinstance(arr, np.ndarray)
    dropped=pd.DataFrame(arr).dropna(*args, **kwarg).values
    if arr.ndim==1:
        dropped=dropped.flatten()
    return dropped

x = np.array([1400, 1500, 1600, np.nan, np.nan, np.nan ,1700])
y = np.array([[1400, 1500, 1600], [np.nan, 0, np.nan] ,[1700,1800,np.nan]] )


print('='*20+' 1D Case: ' +'='*20+'\nInput:\n',x,sep='')
print('\ndropna:\n',dropna(x),sep='')

print('\n\n'+'='*20+' 2D Case: ' +'='*20+'\nInput:\n',y,sep='')
print('\ndropna (rows):\n',dropna(y),sep='')
print('\ndropna (columns):\n',dropna(y,axis=1),sep='')

print('\n\n'+'='*20+' x[np.logical_not(np.isnan(x))] for 2D: ' +'='*20+'\nInput:\n',y,sep='')
print('\ndropna:\n',x[np.logical_not(np.isnan(x))],sep='')

परिणाम:

==================== 1D Case: ====================
Input:
[1400. 1500. 1600.   nan   nan   nan 1700.]

dropna:
[1400. 1500. 1600. 1700.]


==================== 2D Case: ====================
Input:
[[1400. 1500. 1600.]
 [  nan    0.   nan]
 [1700. 1800.   nan]]

dropna (rows):
[[1400. 1500. 1600.]]

dropna (columns):
[[1500.]
 [   0.]
 [1800.]]


==================== x[np.logical_not(np.isnan(x))] for 2D: ====================
Input:
[[1400. 1500. 1600.]
 [  nan    0.   nan]
 [1700. 1800.   nan]]

dropna:
[1400. 1500. 1600. 1700.]

3

यदि आप उपयोग कर रहे हैं numpy

# first get the indices where the values are finite
ii = np.isfinite(x)

# second get the values
x = x[ii]

1

सबसे सरल तरीका है:

numpy.nan_to_num(x)

प्रलेखन: https://docs.scipy.org/doc/numpy/reference/generated/numpy.nan_to_num.html


2
एसओ में आपका स्वागत है! आपके द्वारा प्रस्तावित समाधान समस्या का जवाब नहीं देता है: आपका समाधान NaNएक बड़ी संख्या के साथ प्रतिस्थापित करता है , जबकि ओपी ने तत्वों को पूरी तरह से हटाने के लिए कहा।
पियर पाओलो

0

इस फिल्टर करने के लिए अपने दृष्टिकोण है ndarray , "एक्स" Nans और infs के लिए

मैं बिना किसी NaNऔर के बिना पंक्तियों का एक नक्शा बनाता हूं inf:

idx = np.where((np.isnan(X)==False) & (np.isinf(X)==False))

idx एक tuple है। यह दूसरे स्तंभ ( idx[1]) सरणी, जहां कोई के सूचकांकों में शामिल है NaN है और न ही inf जहां पंक्ति में मिल गया।

फिर:

filtered_X = X[idx[1]]

filtered_Xएक्स के बिना होता है NaN और न ही inf


0

@ jmetz का जवाब शायद सबसे ज्यादा लोगों की जरूरत है; हालाँकि, यह एक आयामी आयाम देता है, उदाहरण के लिए यह मेट्रिसेस में संपूर्ण पंक्तियों या स्तंभों को हटाने के लिए अनुपयोगी बनाता है।

ऐसा करने के लिए, किसी को तार्किक आयाम को एक आयाम में कम करना चाहिए, फिर लक्ष्य सरणी को अनुक्रमित करना चाहिए। उदाहरण के लिए, निम्नलिखित उन पंक्तियों को हटा देगा जिनमें कम से कम एक NaN मान हो:

x = x[~numpy.isnan(x).any(axis=1)]

अधिक विवरण यहाँ देखें ।

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