무효 클릭 IP 추적 중...
파이썬/pandas

[판다스 기초] dropna를 통해 결측치가 있는 행|열 제거 방법

꼬예 2021. 7. 16.

데이터를 수집하다보면 다양한 결측치들이 포함되어 우리를 힘들게 할때가 많은데요.

 

이번 포스팅에서는 dropna를 통해 우리가 원하는 방식으로 결측값을 처리하는 방법에 대해 배워 보도록 하겠습니다.

 

챗gpt를 이용한 데이터분석과 시각화 마스터하기 >>

 

 

dropna 디폴트 세팅

import pandas as pd
import numpy as np

test_data = {'상호명' :['상호네', '현정이네', '문영이네', '동엽이네', '우제네'],
            '사과' : [1000, 900, 800, 1000, 200],
            '배' : [1100, 800, 700, 500, 2000],
            '딸기' : [800, np.nan,700,500,1000],
            '포도' : [1500, 900, np.nan, 800, 900]}

df = pd.DataFrame(test_data)
df.set_index('상호명', inplace=True)
df.dropna()

output :

dropna 메소드에 어떤 인자도 넣지 않은 상태로 디폴트값을 실행시켰을때 위와 같은 결과가 나옵니다. 

정확하게 말하면 디폴트 상태는 df.dropna(axis='index', how='any)입니다.

해당 인자의 의미는 인덱스방향(행)으로 하나씩 훑으면서 nan값이 하나라도 있으면 해당 행을 삭제시키겠다라는 의미입니다.

 

우리 코드에선 '현정이네', '문영이네'에 nan값이 있었기때문에 두 가게가 삭제되었습니다.

 

앞서 how='any'를 맛보았는데요, how='all'일때는 어떤 연산을 수행할까요?

df.dropna(how='all')

import pandas as pd
import numpy as np

test_data = {'상호명' :['상호네', '현정이네', '문영이네', '동엽이네', '우제네'],
            '사과' : [1000, 900, 800, 1000, 200],
            '배' : [1100, 800, 700, 500, 2000],
            '딸기' : [800, np.nan,700,500,1000],
            '포도' : [1500, 900, np.nan, 800, 900]}

df = pd.DataFrame(test_data)
df.set_index('상호명', inplace=True)
df.dropna(how='all')

output :

변화가 없습니다.  왜냐하면 all이 의미하는것은 특정 행의 모든값이 다 Nan이어야지 삭제 하겠다는 의미이기 때문입니다.

 

all이 정말 작동하는지 확인하기 위해  아래와 같이 특정 행이 모든 Nan 값인 형태를 만들어 보았습니다.

import pandas as pd
import numpy as np

test_data = {'상호명' :['상호네', '현정이네', '문영이네', '동엽이네', '우제네'],
            '사과' : [1000, 900, np.nan, 1000, 200],
            '배' : [1100, 800, np.nan, 500, 2000],
            '딸기' : [800, np.nan,np.nan,500,1000],
            '포도' : [1500, 900, np.nan, 800, 900]}

df = pd.DataFrame(test_data)
df.set_index('상호명', inplace=True)
df.dropna(how='all')

output :

output 결과를 보시면 모든 값이 Nan으로 채워져있던 문영이네가 삭제된것을 알 수 있습니다.

 

이어서 컬럼(열)을 기준으로 nan값이 있는지 확인하는 법을 알아보겠습니다.

기본적으로 디폴트 값이 axis='index'임으로 열을 기준으로 보기위에서는 명시적으로 기입을 해줘야 합니다.

df.dropna(axis = 'columns', how='any')

import pandas as pd
import numpy as np

test_data = {'상호명' :['상호네', '현정이네', '문영이네', '동엽이네', '우제네'],
            '사과' : [1000, 900, 800, 1000, 200],
            '배' : [1100, 800, 700, 500, 2000],
            '딸기' : [800, np.nan,700,500,1000],
            '포도' : [1500, 900, np.nan, 800, 900]}

df = pd.DataFrame(test_data)
df.set_index('상호명', inplace=True)

output :

이번에는 axis ='columns'로 지정해주었기때문에 column 방향으로 하나씩 값을 훑으면서 nan값이 하나라도 있다면 삭제 하게 됩니다. 

 

nan값이 각각 한개씩 있던  딸기와 포도가 삭제 된 걸 알 수있죠.

 

때로 특정 컬럼에만 nan이있는지 확인하고 있을 경우 삭제하고 싶을때가 있죠.

그럴때는 subset 이라는 argument를 이용하면 됩니다.

 

dropna(subset=['column'])

우선 딸기가 nan값인 과일가게를 삭제 시키고싶을땐 어떻게할까요?

(즉, 딸기가 아닌 다른 과일이 nan인 상황은 신경쓰지 않겠다는거죠.)

# axis = 1

import pandas as pd
import numpy as np

test_data = {'상호명' :['상호네', '현정이네', '문영이네', '동엽이네', '우제네'],
            '사과' : [1000, 900, 800, 1000, 200],
            '배' : [1100, 800, 700, 500, 2000],
            '딸기' : [800, np.nan,700,500,1000],
            '포도' : [1500, 900, np.nan, 800, 900]}

df = pd.DataFrame(test_data)
df.set_index('상호명', inplace=True)
df.dropna(axis = 'index', how='any', subset=['딸기'])

output :

output을 보시면 알 수 있듯이 딸기가 nan값이던 '현정이네'는 삭제 되었지만 포도가 nan값인 문영이네는 그대로 있는걸 알 수있습니다. 

 

위 코드에서 how = 'any'라고 작성했는데요 사실 컬럼 하나만 보겠다고할때는 'all'과 'any'의 의미가 없습니다.

어차피 all도 1개이기 때문이죠.

 

그렇다면 subset 2개인 경우를 볼까요?

dropna(subset=['column1', 'column2'])

# how ='all', subset=['column1','column2'])

import pandas as pd
import numpy as np

test_data = {'상호명' :['상호네', '현정이네', '문영이네', '동엽이네', '우제네'],
            '사과' : [1000, 900, 800, 1000, 200],
            '배' : [1100, 800, 700, 500, 2000],
            '딸기' : [800, np.nan,700,500,1000],
            '포도' : [1500, 900, np.nan, 800, 900]}

df = pd.DataFrame(test_data)
df.set_index('상호명', inplace=True)
df.dropna(axis = 'index', how='all', subset=['딸기','포도'])

이번에는 how = 'all', subset에 두개의 컬럼을 지정했습니다. 즉 '딸기', '포도'가 동시에 nan값인 행만 삭제하라는 뜻이지요.

output :

output 을 보시면 삭제된 행이 없습니다. 왜냐하면 nan값이 있긴 하지만 딸기 포도 둘다 Nan값을 만족하는 행은 없기 때문이죠.

 

그러면 'any'를 사용해볼까요?

# how ='any', subset=['column1','column2'])

import pandas as pd
import numpy as np

test_data = {'상호명' :['상호네', '현정이네', '문영이네', '동엽이네', '우제네'],
            '사과' : [1000, 900, 800, 1000, 200],
            '배' : [1100, 800, 700, 500, 2000],
            '딸기' : [800, np.nan,700,500,1000],
            '포도' : [1500, 900, np.nan, 800, 900]}

df = pd.DataFrame(test_data)
df.set_index('상호명', inplace=True)
df.dropna(axis = 'index', how='any', subset=['딸기','포도'])

output :

딸기, 포도 컬럼중 하나만 nan값이 있을 경우 삭제하면 되기 때문에(how= 'any')

nan값을 하나씩 가지고있던 행들이 모두 삭제된것을 알 수 있습니다.

 

 

  • 트위터 공유하기
  • 페이스북 공유하기
  • 카카오톡 공유하기
이 컨텐츠가 마음에 드셨다면 커피 한잔(후원) ☕

댓글