우당탕탕 개발공부
파이썬 데이터 분석 - [ 데이터 정제 ] 본문
결측치
: 누락된 값 , 비어있는 값
결측치 만들기
Numpy 패키지의 np.nan 입력
파이썬에서는 결측치를 Nan으로 표시
df = pd.DataFrame({'sex' : ['M','F', np.nan , 'M','F'],
'score' : [5, 4, 3, 4, np.nan]})
df
Nan이 있는 상태로 연산 시 출력 결과도 Nan
df['score']+1
결측치 확인하기
pd.isna( ) 사용해 결측치 여부를 알 수 있음
True : 결측치
False : 결측치 아닌 값
pd.isna(df)
sex의 3행과 score 5행이 결측치라는 것을 알 수 있음
결측치 빈도 확인
pd.isna( ).sum( )
#결측치 빈도 확인
pd.isna(df).sum()
결측치 있는 행 제거하기
df.dropna( )
subset에 [ ]를 이용해 변수명 입력
# score 결측치 제거 == socre가 결측치가 아닌 행만 출력
df.dropna(subset = ['score'])
추출한 데이터를 변수에 할당 시 결측치가 제거 됐으니 연산하면 Nan없이 결과 출력
df_nomiss = df.dropna( subset = ['score'])
df_nomiss['score']+1
여러 변수에 결측치 없는 데이터 추출
df.dropna( )의 subset = [ ]
df_nomiss = df.dropna( subset = ['score','sex']) # score, sex 결측치 제거
df_nomiss
결측치가 하나라도 있으면 제거
df.dropna( )에 아무 변수도 지정하지 않으면 모든 변수에 결측치가 없는 행만 남김
df_nomiss2 = df.dropna()
df_nomiss2
💥 이 방법은 결측치가 있는 값들을 모두 제거한다는 점에서 간편하지만, 분석에 필요한 행까지 손실된다는 단점이 있음
따라서 명시적으로 결측치를 제거하는 방법을 권고 !!
결측치 제거하지 않고 분석하기
pd.mean( ), pd.sum( )과 같은 수치 연산 함수는 결측치가 있으면 자동으로 제거하고 연산하는 기능
groupy( )와 agg( )를 이용해 집단별 요약 통계량을 구할 때도 결측치 제거하고 연산
df['score'].mean()
df.groupby('sex').agg( mean_score = ('score','mean'), sum_score = ( 'score','mean'))
💬 자동으로 결측치를 제거하여 편하지만, 결측치가 있는지 모른 채로 데이터를 다루게 된다는 위험이 있음
따라서 결측치가 있는 지 직접 확인하고 pd.isna( ) , df.dropna( )를 이용해 명시적으로 제거하기
결측치 대체하기
결측치를 다른 값으로 대체하면 데이터가 손실되어 분석 결과가 왜곡되는 문제를 보완
df.loc[ , ] 데이터 위치를 지칭하는 역할 | 쉼표 왼쪽 : 행 위치 , 쉼표 오른쪽 : 열 위치
exam.loc[[2, 7, 14],['math']] = np.nan #2, 7, 14행의 math에 Nan 할당
exam
결측치를 평균 값으로 대체하려면
① math의 평균값 구하기
exam['math'].mean()
② df.filldna( ) 이용해 대체
exam['math'] = exam['math'].fillna(55) # math가 Nan이면 55로 대체
exam
exam['math'].isna().sum() #결측치 빈도 확인
이상치
: 정상 범위에서 크게 벗어난 값
이상치 확인하기
df.value_counts( ) 이용해 빈도표 만들기
sort_index( ) 를 적용하면 빈도 기준으로 내림차순 정렬하지 않고, 변수의 값 순서로 정렬
df = pd.DataFrame({ 'sex' : [1,2,1,3,2,1],
'score' : [5,4,3,4,2,6]})
df
df['sex'].value_counts().sort_index()
df['score'].value_counts().sort_index()
결측 처리하기
np.where( )이용해 이상치일 경우 Nan 부여
# sex가 3이면 Nan 부여
df['sex'] = np.where( df['sex'] ==3, np.nan, df['sex'])
df
# score가 5보다 크면 Nan 부여
df['score'] = np.where( df['score']>5 , np.nan , df['score'])
df
이상치를 결측치로 변환했으니 df.dropna( ) 이용해 결측치 제거 후 출력
# 성별에 따른 score 평균
df.dropna( subset = ['sex','score']) \
.groupby('sex') \
.agg( mean_score = ('score','mean'))
🚀 np.where( )은 문자와 Nan을 함께 반환할 수 없음
np.where( )는 반환하는 값중에 문자가 있으면 np.nan을 지정하더라도 결측치 Nan이 아닌 문자 'nan'으로 출력
df.isna( )로 확인해도 모두 False로 반환
df=pd.DataFrame( { 'x1' : [1,1,2,2]}) df['x2'] = np.where( df['x1'] ==1, 'a',np.nan) df
df.isna()
따라서 변수를 문자와 Nan으로 함께 구성하려면
① np.where( )를 이용해 결측치로 만들 값에 문자를 부여
df['x2'] = np.where( df['x1']==1,'a','etc')
② df.replace( )를 이용해 결측치로 만들 문자를 np.nan으로 바꿈
#'etc'를 Nan으로 바꾸기 df['x2'] = df['x2'].replace('etc',np.nan) df
df.isna()
극단치
: 논리적으로 존재할 수 있지만 극단적으로 크거나 작은 값
상자그림 box plot
: 데이터의 분포를 직사각형의 상자 모양으로 표현한 그래프
: 중심에서 멀리 떨어진 값을 점으로 표현하는데, 이를 이용해 극단치의 기준을 정할 수 있음
seaborn패키지의 boxplot( )이용
import seabron as sns
mpg = pd.read_csv('mpg.csv')
sns.boxplot( data = mpg , y = 'hwy')
상자그림 | 값 | 설명 |
상자 아래 세로선 | 아랫수염 | 하위 0~25% 내에 해당하는 값 |
상자 밑면 | 1사분위수(Q1) | 하위 25% 위치 값 |
상자 내 굵은 선 | 2사분위수(Q2) | 하위 50% 위치 값 (=중앙값) |
상자 윗면 | 3사분위수(Q3) | 하위 75% 위치 값 |
상자 위 세로선 | 윗수염 | 하위 75~100% 내에 해당하는 값 |
상자 밖 가로선 | 극단치 경계 | Q1, Q3 밖 1.5 * IQR 내 최대값 |
상자 밖 점 표식 | 극단치 | Q1, Q3 밖 1.5 * IQR을 벗어난 값 |
* IQR(사분위 범위) : 1사분위와 3사분위의 거리
극단치 기준값 구하기
1사분위수, 3사분위수 구하기
df.quantile( )이용해 분위수 구하기
# 하위 25%에 해당하는 1사분위수
pct25 = mpg['hwy'].quantile(.25)
pct25
# 하위 75%에 해당하는 3사분위수
pct75 = mpg['hwy'].quantile(.75)
pct75
IQR 구하기
IQR : 1사분위수와 3사분위수의 거리를 나타냄
iqr = pct75 - pct25
iqr
하한, 상한 구하기
하한 : 1사분위수보다 'IQR의 1.5배'만큼 더 작은 값
상한 : 3사분위수보다 'IQR의 1.5배'만큼 더 큰 값
# 하한
pct25 - 1.5 * iqr
pct75 + 1.5 * iqr
=> 4.5보다 작거나 40.5보다 크면 극단치
극단치 결측 처리하기
np.where( )이용해 기준값을 벗어나면 결측 처리
여러 조건을 입력할 땐, 각 조건을 괄호로 감싸기
# 4.5 ~ 40.5 벗어나면 Nan 부여
mpg['hwy'] = np.where((mpg['hwy'] < 4.5)| (mpg['hwy']>40.5), np.nan , mpg['hwy'])
# 결측치 빈도 확인
mpg['hwy'].isna().sum()
결측치 제거하고 분석하기
mpg.dropna( subset = ['hwy']) \
.groupby('drv') \
.agg( mean_hwy = ('hwy', 'mean'))

처음에 이상치랑 결측치랑 개념이 헷갈려서 코딩하는데 조금 헷갈렸다..ㅎㅎ 이상치를 결측치로 변환 !! 하는 거 잊지말자
결측치 제거하는 건 dropna( ) , 문자는 np.nan해도 문자로 nan이 출력되기 때문에 결측치로 만들 값에 문자 부여 후 replace( )를 사용해 ~ np.nan로 바꾸기 그리고 명시적으로 결측치를 제거하기 !!!
'✍ Study > 데이터 분석' 카테고리의 다른 글
파이썬 데이터 분석 - [ 텍스트 마이닝 ] (0) | 2023.01.11 |
---|---|
파이썬 데이터 분석 - [ 그래프 ] (0) | 2023.01.11 |
파이썬 데이터 분석 - [ 데이터 가공 3편 ] (0) | 2023.01.07 |
파이썬 데이터 분석 - [ 데이터 가공 2편 ] (0) | 2023.01.06 |
파이썬 데이터 분석 - [ 데이터 가공 1편 ] (0) | 2023.01.05 |