본문 바로가기
Study/Python

Python NaN

by 개발새-발 2022. 7. 4.
반응형

Python 에서 nan 값을 다루는 법을 알아봅니다.

NaN 이란?

NaN 값은 ‘Not a Number’ 을 뜻합니다. 숫자가 아니라는 뜻이죠. 0을 0으로 나누거나 음수의 제곱근을 구하고자 하면 정상적인 값을 얻지 못할 것입니다. 그럼에도 반환값을 받아야 하는 경우 nan 값을 받게 됩니다. Python에서는 0/0 을 수항하면 Error를 출력하는데, 다른 언어나 python의 numpy 라이브러리를 사용하는 경우 nan 값이 반환되는 것을 볼 수 있습니다.

# nan returned

a = np.array([1,2,3,0,5])
b = np.array([1,2,3,0,0])

print(a/b) # [ 1.  1.  1. nan inf]

nan 은 IEEE 754 라 하여 부동소수점 연산에 관한 표준에서 소개되었습니다. nan 값은 부동소수점 연산 결과에서 특수한 경우를 나타내기 때문에, nan 값은 float 값의 일종입니다. IEEE 754에 의하면 0.01, 0.00034, 3.141592같은 수들과 같은 비트 표현 방식을 사용하지만, 가능한 패턴 중 특수한 경우들을 nan 이라고 부르는 것입니다. 따라서 nan도 float type의 일종입니다.

nan 값은 연산의 결과가 숫자로 표현될 수 없을 때 사용하기도 하지만, 단순히 값이 부재하는 경우에도 사용합니다.

NaN 특징

Type

nanfloat type 입니다.

print(type(float('NaN'))) # <class 'float'>
print(type(np.nan)) # <class 'float'>
print(type(math.nan)) # <class 'float'>

다른 수와의 연산 결과

nan 은 숫자가 아니기 떄문에 다른 숫자들과 연산이 수행되면 결과로 nan을 받게 됩니다.

x = float('nan')

print( x + 1 ) # nan
print( x * 1 ) # nan
print( x % 1 ) # nan
print( x ** 1 ) # nan

비교 연산 결과

nan 은 다른 수와 순서를 가지지 않습니다. (Unordered) 그렇기 때문에 다른 수와 비교를 비교할 수 없음으로 nan 이 아닌 다른 수와 비교연산을 하였을 때 != 를 제외하고 모두 False 를 반환하게 됩니다.

x = float('nan')

print( x > 1 ) # False
print( x < 1 ) # False
print( x == 1 ) # False
print( x != 1 ) # True

nannan 을 비교하였을 때도 결과는 마찬가지입니다.

x = float('nan')
y = float('nan')

print( x > y ) # False
print( x < y ) # False
print( x == y ) # False
print( x != y ) # True

nannan 과 같지 않습니다. 그렇기 때문에 위 코드에서 같은 x 끼리 비교를 하더라도 결과는 동일합니다.

x = float('nan')

print( x == x ) # False
print( x != x ) # True

값이 NaN인지 확인하기

값이 NaN 인지 확인하는 방법은 다양하고, 사용하는 라이브러리마다 다를 수 있습니다. 아래는 nan 확인을 위한 몇가지 방법입니다.

  • python math module : math.isnan(x)
x = float('nan')

print( math.isnan(x) ) # nan
  • numpy : np.isnan(x)
a = np.array([1,np.nan,3,np.nan,5])

print( np.isnan(a) ) # [False  True False  True False]
  • pandas : isna()
a = np.array([1,np.nan,3,np.nan,5])
b = np.array([1,2,3,np.nan,np.nan])

df = pd.DataFrame({'a':a,'b':b})

print( df.isna() )
# a      b
# 0  False  False
# 1   True  False
# 2  False  False
# 3   True   True
# 4  False   True

nannan 과 비교하였을 떄에도 다르다고 판별되는 성질을 이용하여 isna 함수를 만들어 사용할 수 있습니다,

def isna(x):
    return x != x

NaN 값 다른 값으로 채우기

numpy나 pandas를 이용하여 데이터를 조작할 때 nan 값을 다른 값으로 대체하는 작업은 꽤 존재합니다.

Numpy

numpy 에서 nan 값을 다른 값으로 대체하는 방법입니다. nan 값을 999 로 바꾼다고 가정합니다.

  • isnan() 과 boolean index 사용
a = np.array([1,np.nan,3,np.nan,5])

a[np.isnan(a)] = 999

print(a) # [  1. 999.   3. 999.   5.]
  • nan_to_num() 사용

    이 함수는 nan, inf, -inf 모두를 숫자값으로 바꿔버립니다. nan parameter 값의 기본값은 0입니다.

a = np.array([1,np.nan,3,np.nan,5])

print( np.nan_to_num(a,nan=999) ) # [  1. 999.   3. 999.   5.]

Pandas

pandas 에서 nan 값을 다른 값으로 대체하는 방법입니다. nan 값을 999 로 바꾼다고 가정합니다.

  • fillna() 사용
a = np.array([1,np.nan,3,np.nan,5])
b = np.array([1,2,3,np.nan,np.nan])

df = pd.DataFrame({'a':a,'b':b})

print( df.fillna(999) )
# a      b
# 0    1.0    1.0
# 1  999.0    2.0
# 2    3.0    3.0
# 3  999.0  999.0
# 4    5.0  999.0
  • replace() 사용
a = np.array([1,np.nan,3,np.nan,5])
b = np.array([1,2,3,np.nan,np.nan])

df = pd.DataFrame({'a':a,'b':b})

print( df.replace(np.nan,999) )
# a      b
# 0    1.0    1.0
# 1  999.0    2.0
# 2    3.0    3.0
# 3  999.0  999.0
# 4    5.0  999.0
반응형

댓글