2011-02-26 248 views
37

我有一個2D numpy數組。這個數組中的一些值是NaN。我想用這個數組執行某些操作。例如,考慮數組:將nan值轉換爲零

[[ 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.]] 

我試圖把每一行,一次一個,排序它以相反的順序,從該行獲得最大的3個值,並把他們的平均水平。我試過的代碼是:

這對包含NaN的行不起作用。我的問題是,是否有一種快速的方法將2D numpy數組中的所有NaN值轉換爲零,以便我在排序和其他事情上沒有問題。

+1

'each:map:return isNaN(value)? 0:值' – kirilloid 2011-02-26 01:12:02

+0

@kirilloid:聽起來不錯,示例用法如何? – 2016-06-17 15:08:34

回答

60

這應該工作:

from numpy import * 

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

在上述情況下where_are_NaNs是:

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

哪裏A是您的2D陣列:

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

功能isnan產生一個布爾數組,指示其中NaN值。一個布爾數組可以用來索引相同形狀的數組。把它想象成一個面具。

+0

好的方法來設置 – timger 2014-03-07 10:01:19

-7

你的目的,如果所有的項目都存儲爲str,你只需要使用排序爲你使用然後檢查第一個元素並將其替換爲'0'

>>> 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'] 
+4

如果你使用的是numpy,你的數組將不會是數字的字符串表示。你甚至知道numpy是什麼嗎? – 2011-02-26 03:06:16

+2

你的評論不嚴厲嗎?我知道numpy是什麼,但知道該數組不會是數字的字符串表示形式。我特別沒有從numpy的角度對此做出反應,但從python的角度來看,如果這是有用的。 – 2011-02-26 03:24:16

+0

對陣列重新排序聽起來像是解決這個問題的一種令人困惑的方式。 – holografix 2014-06-21 16:25:31

21

怎麼樣?

+6

nan_to_num()也會改變無窮 - 在某些情況下這可能不需要。 – Agos 2011-05-10 08:43:30

+0

它也比其他方法慢10倍以上。 – user48956 2018-01-12 20:05:47

2

楠是從未等於楠

if z!=z:z=0 

所以對於2D陣列

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

這不起作用:'entry'是一維數組,因此測試'entry!= entry'不會給出簡單的布爾值,但會引發'ValueError'。 – EOL 2017-08-05 19:20:28

4

drake's answer A碼例如使用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.]]) 
0

可以使用numpy.nan_to_num

numpy.nan_to_num(X):替換INF有限數

的例子(見DOC):

>>> 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]) 
0

你可以使用np.where找到,你必須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

原樣,它不起作用,你需要將'np.where(np.isnan(a),a,0)'改爲'np.where(〜np.isnan(a),a,0)'。這可能與使用的版本不同。 – TehTris 2018-03-01 23:21:12

+1

@TehTris你是對的,謝謝。我將它改爲'b = np.where(np.isnan(a),0,a)',我認爲這更直接,然後是'〜'。 – 2018-03-02 05:22:24

0

可以使用lambda函數,一維數組的例子:

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

這會給你的結果:

[0, 2, 3]