[KT 에이블스쿨 5기] DX트랙 3주 2일차 복습_데이터프레임 변경
**셀프 복습용으로 작성한 것이라 실수가 있을 수 있습니다!
혹시 실수를 발견하시면 댓글로 알려주시면 감사드리겠습니다 :)
06 데이터프레임 변경 (1) (이어서)
열 삭제
무엇이든 삭제할 때는 무조건 확인 또 확인, 조심!!!!!!!!!!
1) 열 하나 삭제
- df.drop('열 이름', axis=1, inplace=True): 열을 삭제하려면 axis=1로 줘야 함!
- 생략하거나 axis=0으로 작성하면 행이 삭제됨 (기본값), inplace=True 옵션 꼭!
- 열 삭제 후 코드를 재실행하면 오류 발생 → 이미 제거된 열이기 때문에!
2) 여러 열 삭제
- 변수 = ['열 이름1', '열 이름2']: 제거할 열을 리스트로 미리 선언
- df.drop( 변수, axis=1, inplace=True)
- 주로 제거할 리스트 이름의 변수는 drop_cols 활용함
범주값 변경
삭제한 데이터를 머신에 넘겨줘야 하는 경우가 있음!
머신에는 숫자만 인식하기 때문에 문자열이 포함된 데이터를 넘겨줄 수는 없음 (오류 발생)
→ 문자를 숫자화하는 범주값 변경이 데이터 전처리의 마지막 과정!
1) 데이터가 시각화를 통해 변동을 보여주기 위한 방향
2) 머신에게 던져주기 위한 방향
어떤 방향인지에 따라 데이터 전처리 과정이 달라짐!
df['x'] = df['x'].map({'바꿀 문자열1': 숫자1, '바꿀 문자열2': 숫자2})
- 바꾸고 싶은 값의 전체와 개수를 df['열 이름'].value_counts() 메서드로 먼저 확인!
- 값 변경 후 코드를 재실행하면 오류 발생 → 이미 바뀐 열이기 때문에!
***언급하지 않은 문자열은 NaN(결측치로 나타남)
df['x'] = df['x'].replace({바꿀 숫자1: '문자열1', 바꿀 숫자2: '문자열2' }) # 숫자 → 문자로도 변경 가능!
- 바꾸고 싶은 값의 전체와 개수를 df['열 이름'].value_counts() 메서드로 먼저 확인!
- 값 변경 후 코드를 재실행하면 오류 발생 → 이미 바뀐 열이기 때문에!
***언급하지 않은 문자열은 그대로 둠
범주값 만들기
- 이산화(Discretization): 연속값을 구간을 나누어 범주값으로 표현하는 과정
1) cut() 함수: 크기를 기준으로 구간을 나누고 싶을 때 cut()함수를 사용
범위 개수를 지정하면 자동으로 크기를 기준으로 나눔!
bin = [-np.inf, 60, 70, 80, 90, np.inf]
label = list('abcd')
df['그룹 이름'] = pd.cut(df['열 이름'], bins=bin, labels=label)
; 단위 안에 들어가는 데이터의 개수는 알 수 없다!
bin = [-np.inf(음의 무한대), 60, 70, 80, 90, np.inf(양의 무한대)]
**여기서 모든 숫자는 초과를 의미, 60초과부터 70까지, 70초과부터 80까지
bins = 5 이렇게 작성하면 같은 크기로 5분할 (최솟값 최댓값을 기준으로 5분할 ex) 0~100: 0, 20, 40, 60, 80, 100)
label = 구간별 이름을 리스트로 선언 (구간과 개수가 동일해야 함!)
*사분위 값으로 구간 나누기
- describe() 기술통계로 사분위값 확인 후, 변수 q1, q2, q3에 각각 인덱스값 저장
# 사분위수
q1 = df['열 이름'].describe()['25%'] #인덱스값을 주는 것
q2 = df['열 이름'].describe()['50%']
q3 = df['열 이름'].describe()['75%']
2) qcut() 함수: 개수를 기준으로 구간을 나누고 싶을 때 qcut()함수를 사용
범위 개수를 지정하면 자동으로 동일한 개수를 갖는 구간이 만들어짐
df['그룹 이름'] = pd.qcut(df['열 이름'], 구간 개수, list('구간 이름'))
→ qcut에서 구간 개수를 4로 지정하면 사분위 값으로 구간 나눈 것과 같은 결과가 나옴
06 데이터프레임 변경 (2)
결측치 처리
NaN 값, 즉 결측치는 정확한 분석을 방해함, NaN 값을 만나면 오류가 발생하는 함수도 있음!
→ NaN 값은 제거하든지 다른 값 (ex. 평균값, 최빈값 등)으로 채워야 함
결측치 찾기
1) info() 메서드로 확인: 값 개수로 결측치 존재 여부 확인
→ 다른 열 개수보다 적으면 결측치가 있는 것으로 추측
2) isnull(), notnull() 메서드 사용
- isnull(): 결측치면 True, 유효한 값이면 False를 반환 (isna()도 사용 가능)
- notnull(): 결측치면 False, 유효한 값이면 True를 반환 (notna()도 사용 가능)
- sum(): True값의 개수, 열의 결측치 개수를 확인할 수 있음! (따라서 보통 df.isna().sum()을 세트로 사용해서 확인)
#열의 결측치 개수 확인
df.isna().sum()
#결측치 비율 확인(두 개 다 가능)
df.isna().sum() / len(df) *100
df.isna().mean() * 100
결측치 제거
dropna() 메서드로 결측치가 있는 열이나 행을 제거할 수 있음!
inplace=True 옵션 지정해야 해당 데이터프레임에 실제로 반영
- axis=0: 행 제거(기본값)
- axis=1: 열 제거
1) 어떤 열이든 결측치가 있는 행 제거
- 결측치가 있는 모든 행을 제거
- 삭제할 때는 꼭 확인이 필요하므로 변수 = df.copy()해서 사용하기도 함
2) 특정 열에 결측치가 있는 행 제거
- subset 옵션에 열을 지정해 해당 열에 결측치가 있는 행을 제거!
# 특정 열에 있는 결측치 행을 제거
df.dropna(subset=['열 이름'], axis=0, inplace=True)
3) 결측치가 있는 모든 열 제거
- axis=1 옵션을 지정해서 열을 제거
결측치 채우기
- fillna() 메서드를 사용해 결측치 다른 값으로 채울 수 있음
1) 평균값으로 채우기
# 열의 평균값 구하기
변수 = df['열 이름'].mean()
#결측치를 평균값으로 채우기
df['열 이름'].fillna(평균 넣은 변수, inplace=True)
2) 특정 값으로 채우기
#특정 열의 결측치를 0으로 채우기
df['열 이름'].fillna(0, inplace=True)
3) 직전 행의 값 또는 다음 행의 값으로 채우기
- 데이터 유형에 따라 하나 빈 데이터가 있을 때 앞이나 뒤의 값을 채워도 상관이 없다!
(날짜 또는 시간의 흐름에 따른 값을 갖는 시계열 데이터 처리 시 유용)
ex) 날씨 = 어제와 오늘의 기온은 크게 차이나지 않기 때문에 오늘이 결측치면 어제 기온으로 채워도 됨!
ex) 탑승객의 나이 = 두 번째 탄 사람의 나이가 결측치일 때 첫 번째 탄 사람이나 세 번째로 탄 사람의 나이로 채우면 의미가 없음!
- method='ffill': 바로 앞의 값으로 변경(Forward Fill)
- method='bfill': 바로 다음 값으로 변경(Backward Fill)
# 특정 열의 누락된 값을 바로 앞의 값으로 채우기
df['열 이름'].fillna(method='ffill', inplace=True)
# 특정 열의 누락된 값을 바로 뒤의 값으로 채우기
df['열 이름'].fillna(method='bfill', inplace=True)
4) 선형보간법으로 채우기
- interpolate() 메서드를 사용해 선형보간법으로 채울 수 있음
# 선형보간법으로 채우기
df['열 이름'].interpolate(method='linear', inplace=True)
df['열 이름'].interpolate(method='linear', inplace=True)
가변수(Dummy Variable) 만들기
가변수는 일정하게 정해진 범위의 값을 갖는 데이터(범주형 데이터) → 독립된 열로 변환한 것
** 머신러닝에 넘기기 직전에 꼭 하는 가변수화 why? 머신러닝 알고리즘 사용하려면 숫자로 변환해야 함
가변수를 만드는 과정을 One-Hot-Encoding이라고 부르기도 함
get_dummies() 함수를 사용해 가변수화
- 가변수화의 목적
1) 문자열로 되어있는 범주값을 숫자로 바꾸기 위해
2) 숫자의 의미가 없는 분류가 숫자로서 구분되게 만들기 위해서 (1반 2반 3반...)
범주형 변수 확인
- info() 메서드를 활용해 문자열 값을 갖는 열을 확인! (object로 나오는 값들)
변수 개별 처리
- columns 옵션에 열을 하나 지정해 처리할 수 있음, 자동으로 원본 열 제거, 열 이름이 prefix로 사용됨
- drop_first=True(열 하나 날리는 것의 의미), dtype=int 옵션 필수!
Drink | Drink_Yes | Drink_No |
Yes | 1 | 0 |
No | 0 | 1 |
No | 0 | 1 |
→ 위의 경우, 머신러닝에서 Drink_Yes열과 Drink_No열은 같은 말을 하고 있다고 인식해 포인트가 분산되고 있음
→ 따라서 하나는 제거해도 됨! (다중공선성)
#특정 열 가변수화
변수(dumm_cols) = ['열 이름']
df = pd.get_dummies(tip, columns=변수(dumm_cols), drop_first=True, dtype=int)
일괄 처리
- columns 옵션에 대상 열을 리스트로 지정해 한 번에 처리, 자동으로 원본 열 제거, 열 이름이 prefix로 사용됨
- columns 옵션을 지정하지 않으면 문자열 값을 갖는 열 모두를 대상으로 함!
# 여러 범주형 변수를 가변수화
변수(dumm_cols) = ['열 이름1', '열 이름2', '열 이름3']
df = pd.get_dummies(df, columns=변수(dumm_cols), drop_first=True, dtype=int)
#모든 문자열에 대한 가변수화
df = pd.get_dummies(df, drop_first=True, dtype=int)