nan değerini sıfıra dönüştür


95

2B uyuşuk dizilim var. Bu dizideki değerlerden bazıları NaN. Bu diziyi kullanarak belirli işlemleri gerçekleştirmek istiyorum. Örneğin diziyi düşünün:

[[   0.   43.   67.    0.   38.]
 [ 100.   86.   96.  100.   94.]
 [  76.   79.   83.   89.   56.]
 [  88.   NaN   67.   89.   81.]
 [  94.   79.   67.   89.   69.]
 [  88.   79.   58.   72.   63.]
 [  76.   79.   71.   67.   56.]
 [  71.   71.   NaN   56.  100.]]

Her satırı birer birer almaya çalışıyorum, satırdan en fazla 3 değer elde etmek ve ortalamasını almak için ters sırayla sıralamak. Denediğim kod:

# nparr is a 2D numpy array
for entry in nparr:
    sortedentry = sorted(entry, reverse=True)
    highest_3_values = sortedentry[:3]
    avg_highest_3 = float(sum(highest_3_values)) / 3

Bu, içeren satırlar için çalışmaz NaN. Sorum şu ki, NaN2D numpy dizisindeki tüm değerleri sıfıra dönüştürmenin hızlı bir yolu var mı , böylece sıralama ve yapmaya çalıştığım diğer şeylerle hiçbir sorun yaşamıyorum.


1
each: map: return isNaN(value) ? 0 : value
kirilloid

@kirilloid: kulağa hoş geliyor, örnek kullanıma ne dersiniz?
serv-inc

Yanıtlar:


124

Bu çalışmalı:

from numpy import *

a = array([[1, 2, 3], [0, 3, NaN]])
where_are_NaNs = isnan(a)
a[where_are_NaNs] = 0

Yukarıdaki durumda, burada_are_NaNs:

In [12]: where_are_NaNs
Out[12]: 
array([[False, False, False],
       [False, False,  True]], dtype=bool)

139

A2D diziniz nerede :

import numpy as np
A[np.isnan(A)] = 0

İşlev isnan, NaNdeğerlerin nerede olduğunu gösteren bir bool dizisi üretir . Bir boole dizisi, aynı şekle sahip bir diziyi indekslemek için kullanılabilir. Bunu bir maske gibi düşünün.


40

Nan_to_num () nasıl olur ?


11
nan_to_num () da sonsuzlukları değiştirir - bu bazı durumlarda istenmeyen olabilir.
Agos

11
Ayrıca diğer yöntemlere göre> 10x yavaştır.
user48956

7
Tat "> 10x yavaş" ifadesinden emin olmadığım için kontrol ettim. Aslında, o kadar yavaştır. Bunu işaret ettiğiniz için teşekkürler.
Gabriel

16

Bulunduğunuz np.whereyeri bulmak için kullanabilirsiniz NaN:

import numpy as np

a = np.array([[   0,   43,   67,    0,   38],
              [ 100,   86,   96,  100,   94],
              [  76,   79,   83,   89,   56],
              [  88,   np.nan,   67,   89,   81],
              [  94,   79,   67,   89,   69],
              [  88,   79,   58,   72,   63],
              [  76,   79,   71,   67,   56],
              [  71,   71,   np.nan,   56,  100]])

b = np.where(np.isnan(a), 0, a)

In [20]: b
Out[20]: 
array([[   0.,   43.,   67.,    0.,   38.],
       [ 100.,   86.,   96.,  100.,   94.],
       [  76.,   79.,   83.,   89.,   56.],
       [  88.,    0.,   67.,   89.,   81.],
       [  94.,   79.,   67.,   89.,   69.],
       [  88.,   79.,   58.,   72.,   63.],
       [  76.,   79.,   71.,   67.,   56.],
       [  71.,   71.,    0.,   56.,  100.]])

1
olduğu gibi çalışmıyor, değiştirmeniz np.where(np.isnan(a), a, 0)gerekiyor np.where(~np.isnan(a), a, 0). Bu, kullanılan sürümlerde bir farklılık olabilir.
TehTris

1
@TehTris haklısın, teşekkürler. Bunu düşündüğümden b = np.where(np.isnan(a), 0, a)daha kolay olana değiştirdim ~.
Anton Protopopov

10

Drake'in kullanacağı yanıt için bir kod örneği nan_to_num:

>>> import numpy as np
>>> A = np.array([[1, 2, 3], [0, 3, np.NaN]])
>>> A = np.nan_to_num(A)
>>> A
array([[ 1.,  2.,  3.],
       [ 0.,  3.,  0.]])

3

Numpy.nan_to_num'u kullanabilirsiniz :

numpy.nan_to_num (x): Değiştir nan ile sıfır ve inf ile sonlu sayılar .

Örnek (belgeye bakın):

>>> np.set_printoptions(precision=8)
>>> x = np.array([np.inf, -np.inf, np.nan, -128, 128])
>>> np.nan_to_num(x)
array([  1.79769313e+308,  -1.79769313e+308,   0.00000000e+000,
        -1.28000000e+002,   1.28000000e+002])

1

nan asla nan'a eşit değildir

if z!=z:z=0

yani bir 2D dizi için

for entry in nparr:
    if entry!=entry:entry=0

Bu işe yaramaz: entry1 boyutlu bir dizidir, bu nedenle test entry != entrybasit bir mantıksal değer vermez, ancak yükseltir ValueError.
Eric O Lebigot

-1

1B dizisi için bir örnek olan lambda işlevini kullanabilirsiniz:

import numpy as np
a = [np.nan, 2, 3]
map(lambda v:0 if np.isnan(v) == True else v, a)

Bu size sonucu verecektir:

[0, 2, 3]

-8

Amaçlarınız için, tüm öğeler olarak depolanıyorsa strve siz kullandığınız gibi sıralı kullanıyorsanız ve ardından ilk öğeyi kontrol edip '0' ile değiştirin

>>> l1 = ['88','NaN','67','89','81']
>>> n = sorted(l1,reverse=True)
['NaN', '89', '88', '81', '67']
>>> import math
>>> if math.isnan(float(n[0])):
...     n[0] = '0'
... 
>>> n
['0', '89', '88', '81', '67']

6
Yorumunuz biraz sert değil mi? Numpy'nin ne olduğunu biliyorum, ama dizinin sayıların dize temsili olmayacağını biliyordum. Bunu özellikle uyuşuk bakış açısından değil, yararlı olsaydı python'un bakış açısından ele aldım.
Senthil Kumaran

2
Diziyi yeniden düzenlemek, bunu çözmenin kafa karıştırıcı bir yolu gibi görünüyor.
holografix

Dizimin sırasını korumam gerekiyor. Dizinizde birden fazla 'NaN' varsa çalışmaz.
3nrique0
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.