KT 에이블스쿨 복습

[KT 에이블스쿨 5기] DX트랙 3주 2일차 복습_데이터프레임 변경

리니끄적 2024. 3. 5. 20:43

**셀프 복습용으로 작성한 것이라 실수가 있을 수 있습니다!
혹시 실수를 발견하시면 댓글로 알려주시면 감사드리겠습니다 :)

 

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)