Matlab: isnan 関数

informatics/commands_matlab/isnan_matlab
8-2-2017 updated

  1. isnan で欠損値 NaN を探す
  2. NaN を他の数値で置き換える
  3. NaN を含む行を取り除く

広告

isnan で欠損値 NaN を探す

isnanは、欠損値 NaN (Not-a-Number) に対して 1 を、数値に対して 0 を返す論理式の関数である。同様に、無限要素 Inf を検出する ininf や、有限要素を検出する isfinite (NaN, Inf 以外の場合に 1 を返す) がある。

>>isnan ([pi NaN Inf -Inf]) は [0 1 0 0] となる。つまり、円周率、無限大、マイナスの無限大は数値とみなされる。

行列に対して実行すると、

>> A=rand(3,3)
A =
0.4218    0.9595    0.8491
0.9157    0.6557    0.9340
0.7922    0.0357    0.6787

>> A(2,2)=NaN
A =
0.4218    0.9595    0.8491
0.9157    NaN       0.9340
0.7922    0.0357    0.6787
 

% NaN は、ただアルファベットでタイプすればよい。


>> B=isnan(A)
B =
     0     0     0
     0     1     0
     0     0     0

このように、NaN のみが 1 として表示される。
ここで

>> C=sum(B)
C=
  0     1     0


とそれぞれの列の和をとることができる。これをもう一度繰り返すと

>> D=sum(C)
D = 1

となり、何個の NaN が含まれていたかがわかる。もし、もともとの行列 A が NaN を含まない場合、B は全て 0 であり、D は 0 になる。

isnan を使ってNaNをベクター、行列から取り除く

NaN は not a numberで、しばしば現れる厄介な要素である。以下の方法でこれを数字に置換することができる。

>> A=(1:4:20)
A = 1    5    9    13    17

座標 (1,2) にある数字を NaN に変える。

>> A(1,2)=NaN
A =  1   NaN     9    13    17

>> B=isnan(A)
B =  0     1     0     0     0

>> A(B)=0
A = 1     0     9    13    17

これは、B を設定せずに >> A(isnan(A))=0 としても同じである。
つまり、普通に find や A の値指定で変換する場合と同じである。行列の場合も同様で、

A =     16    2     3     13     
        5     11    10    8    
        9     7     6     12
        4     14    15    1

>> A(2,3)=NaN
A =     16    2     3     13     
        5     11    NaN   8    
        9     7     6     12
        4     14    15    1

>> A(isnan(A))=0;
A =     16    2     3     13     
        5     11    0     8
        9     7     6     12
        4     14    15    1
 

このように、isnan で指定すると置換が可能になる。
ただし、NaN は数ではないので、==0 という概念は成り立たないことに注意する必要がある。つまり、

>> A(A==NaN)=0
A =     16    2     3     13     
        5     11    NaN   8
        9     7     6     12
        4     14    15    1


となり、== を使って 0 を代入することはできない。

isnan で NaN を含む行を取り除く

MATLAB では、行を取り除く作業は空行列 [ ] の挿入によって行う。 行列の扱い方も参照。 もっと良い方法があるのかもしれないが、NaN が複数含まれている行列から、行を順番に取り除いていくスクリプト。

A=randn(10,5);
A(1,3)=NaN; A(4,1)=NaN; % Introcude NaN
rowno=size(A,1); % Number of 1st dimension of matrix A (row)
columnno=size(A,2); % Number of 2nd dimension of matrix A (column)
nanpos=isnan(A);
count=0;

for tempr=1:rowno
for tempc=1:columnno;
if nanpos(tempr,tempc)==1;
A(tempr-count,:)=[];
count=count+1;
end
end
end

count は、1 回 NaN を取り除いた後に行がずれるのを補正している。


1 行または 1 列の行列の場合

たとえば、A が NaN を含む 1 x 100 行列だった場合には、話は簡単で、

>> B = isnan (A)
>> A(B)=[]

で OK である。NaN がもともと 20 個含まれていたときは、A が 1 x 80 行列に変換される。

コメント欄



フォーラムを作ったので、各ページにあるコメント欄のうち、コメントがついていないものは順次消していきます。今後はフォーラムをご利用下さい。管理人に直接質問したい場合は、下のバナーからブログへ移動してコメントをお願いします。

References

  1. Matlab - 大淵武史の備忘録. Link.