Bir diziden nan değerlerini kaldırma


223

Ben dizi benim nan değerleri kaldırmak nasıl anlamaya istiyorum. Dizim şuna benzer:

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

nanDeğerleri nasıl kaldırabilirim x?


Açıkça söylemek gerekirse, "NaN'leri kaldır" ile sadece boş olmayan değerlerin alt kümesini filtrelemek istersiniz . "
NaN'leri bir

Yanıtlar:


362

Dizileriniz için numpy kullanıyorsanız,

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

eşdeğer bir

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

[Eklenen steno için chbrown'a teşekkürler]

açıklama

İç işlev, her yerde sayı olmayan bir numpy.isnandeğere sahip olan bir boole / mantıksal dizi döndürür . Biz tam tersini istiyoruz, biz, mantıksal-olmayan operatörünü kullanmak içeren bir dizi almak için her yerde s olan geçerli bir sayı.Truex~Truex

Son olarak, bu mantıksal diziyi orijinal dizinin dizinini oluşturmak x, yalnızca NaN olmayan değerleri almak için kullanırız.


31
Veyax = x[numpy.isfinite(x)]
tembel1

14
Veya x = x[~numpy.isnan(x)], mutzmatronun orijinal cevabına eşdeğerdir, ancak daha kısadır. Sonsuzluklarınızı etrafta tutmak istiyorsanız, bunu bilin numpy.isfinite(numpy.inf) == False, tabii ki, ama ~numpy.isnan(numpy.inf) == True.
chbrown

8
Bunu bir ndarray ile çözmek ve boyutları korumak isteyen insanlar için, numpy kullanın burada :np.where(np.isfinite(x), x, 0)
BoltzmannBrain

1
TypeError: yalnızca tamsayı skaler diziler skaler bir dizine dönüştürülebilir
towry

1
@towry: bu oluyor çünkü girdiniz xbir numpy dizisi değil. Mantıksal indeksleme kullanmak istiyorsanız, bu bir dizi olmalıdır - örneğinx = np.array(x)
jmetz

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

v! = v yalnızca NaN için olduğundan listeler ve numpy dizileri için çalışır


5
Bir hack, özellikle dizeleri ve nanslar gibi karışık türlere sahip bir dizi nesneden nansları filtrelediğiniz durumda özellikle yararlıdır.
Austin Richardson

Çok temiz bir çözüm.
Moondra

2
Bu akıllıca görünebilir, ancak mantığı ve teorik olarak diğer nesneler (özel sınıflar gibi)
gizlerse

Ayrıca yararlıdır, çünkü xtipin çözümlerinin aksine sadece bir kez belirtilmesi gerekir x[~numpy.isnan(x)]. Bu, xuzun bir ifade ile tanımlandığında ve bu uzun ifadenin sonucunu saklamak için geçici bir değişken oluşturarak kodu karıştırmak istemediğinizde kullanışlıdır .
Christian O'Reilly

34

Bunu dene:

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

Daha fazla bilgi için Liste Anlamaları'nı okuyun .


5
Numpy kullanıyorsanız hem cevabım hem de @ lazy1, liste kavrayışından neredeyse daha hızlı bir büyüklük sırasıdır - lazy1'in çözümü biraz daha hızlıdır (teknik olarak herhangi bir sonsuzluk değeri döndürmez).
jmetz

Parantezleri unutma :)print ([value for value in x if not math.isnan(value)])
hipers

Eğer üst cevap gibi numpy kullanıyorsanız, bu liste anlama cevabını np paketi ile kullanabilirsiniz: Yani [value for value in x if not np.isnan(value)]
nans

23

Benim için @jmetz cevabı işe yaramadı, ancak pandaları kullanmak isnull () işe yaradı.

x = x[~pd.isnull(x)]

6

Yukarıdakileri yapmak:

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

veya

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

Aynı değişkene (x) sıfırlamanın gerçek nan değerlerini kaldırmadıklarını ve farklı bir değişken kullanmak zorunda olduklarını gördüm. Farklı bir değişkene ayarlamak, nansları kaldırdı. Örneğin

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

Bu tuhaf; dokümanlara göre , boolean dizi indeksleme (ki bu), görünüşte "her zaman verilerin bir kopyasını döndürür" gibi gelişmiş indeksleme altındadır , bu nedenle xyeni değerle (yani NaN'ler olmadan ...) üzerine yazmalısınız. . Bunun neden olabileceğiyle ilgili daha fazla bilgi verebilir misiniz?
jmetz

5

Başkaları tarafından gösterildiği gibi

x[~numpy.isnan(x)]

İşler. Ancak numpy dtype yerel bir veri türü değilse, örneğin nesne ise bir hata atar. Bu durumda pandaları kullanabilirsiniz.

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

4

Kabul edilen cevap 2d diziler için şekil değiştirir. Burada, Pandas dropna () işlevselliğini kullanarak bir çözüm sunuyorum . 1D ve 2D diziler için çalışır. 2B durumda , içeren satırı veya sütunu bırakmak için hava durumunu seçebilirsiniz 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='')

Sonuç:

==================== 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

Kullanıyorsanız numpy

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

# second get the values
x = x[ii]


0

Bu benim ndarray'i filtreleme yaklaşımım ve infs için "X" ,

Ben aşağıdaki gibi herhangi bir NaNve olmadan satırların bir harita oluşturmak inf:

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

idx bir demettir. İkinci sütun ( idx[1]) dizinin indekslerini içerir, burada NaN veya inf yok bulunmaz.

Sonra:

filtered_X = X[idx[1]]

filtered_XX içeren olmadan NaN ne inf.


0

@ jmetz'nin cevabı muhtemelen çoğu insanın ihtiyaç duyduğu ; ancak tek boyutlu bir dizi verir, örneğin matrislerdeki tüm satırların veya sütunların kaldırılmasını kullanılamaz hale getirir.

Bunu yapmak için, mantıksal diziyi bir boyuta indirmeli, sonra hedef diziyi dizine eklemelidir. Örneğin, aşağıdakiler en az bir NaN değerine sahip satırları kaldıracaktır:

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

Daha fazla ayrıntıyı burada görebilirsiniz .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.