

💡 df_processed = df.copy()
: df = 원본 데이터
: df_processed = 전처리(결측치 처리 등)용 복사본
- 원본 망가지는 것을 방지하기 위해 원본을 복사함.
💡 .isnull().sum()
- .isnull() → 결측치(True/False로 바꿔줌)
- .sum() → True를 1로 보고 더함
: df['Age'].isnull().sum()은 Age에 입력된 결측치를 세달라는 말
.
[차이 확인하기]
- df.isnull() : 데이터가 비어있으면 True, 채워져 있으면 False로 된 표가 출력됨
- df.isnull().sum() : True(1)가 몇 개인지 컬럼별 결측치 개수가 계산됨
- df.isnull().sum() >0 : 결측치가 하나라도 있으면 True
- df.isnull().sum()[df.isnull().sum() > 0] : 0보다 큰(결측치가 하나라도 있는) 컬럼들만 쏙 골라내서 다시 목록을 생성

💡 fillna
- 이름 그대로 "채우다(fill)"와 "결측치(na)"가 합쳐진 단어
- 데이터프레임 내의 빈칸 즉, 결측치(Missing Value / NaN) 특정 값으로 채워주는 아주 중요한 함수
- 컴퓨터는 '비어있는 값(NaN)'이 있으면 연산을 하거나 머신러닝 모델을 학습시킬 때 오류를 일으키는 경우가 많기 때문에 합리적인 값으로 메꿔줘야 하는데, 이때 fillna를 사용
➡️ 예) df['Age'].fillna(0) : 칸을 모두 0으로 채워라
➡️ 예) df['Grade'].fillna('Unknown') : 문자열로 채우기
💡 pd.to_numeric(...)
- 데이터를 숫자형으로 강제로 바꾸라는 명령어
- 예) [22.5, '28.3', 'NULL'] → [22.5, 28.3, ???]
💡 errors='coerce'
- 변환 못하는 값은 에러 내지 말고 NaN으로 바꾸는 명령문
- 예) df_processed['BMI']
.
➡️ coerce 없이 (기본 또는 errors='raise') pd.to_numeric(df_processed['BMI'])를 입력 시
→ 에러(ValueError: could not convert string to float: 'NULL')
→ 'NULL', 'abc'는 숫자가 아니니까
.
➡️ errors='coerce' 사용
pd.to_numeric(df_processed['BMI'], errors='coerce')
[22.5, 28.3, NaN, NaN]- 문제 있는 데이터를 버리지 말고, 일단 NaN으로 바꿔서 이후 처리 가능하게 만드는 과정 → .fillna() 또는 삭제 가능해짐

💡 duplicated()
- 중복된 행을 True로 표시
- 첫 번째는 살리고, 그 다음부터 중복으로 봄
- duplicated().sum()은 중복된 행의 갯수가 출력됨.
.
‼️subset=은copy 때문이 아니라“어떤 기준으로 중복을 볼지 정하는 옵션”
예) df.duplicated(subset=['PatientID'])
: 전체 행 말고, PatientID 컬럼만 보고 중복을 판단 → ID가 같으면 나머지가 달라도 “중복” 처리됨
💡 drop_duplicates()
- 중복 제거
dfprocessed = df_processed._drop_duplicates(subset=['PatientID'], keep='last')
: PatientID 기준으로 중복된 데이터 중 하나만 남기고 삭제
💡 keep 옵션
- 중복된 것들 중 어떤 것을 살릴 것인가?를 결정
➡️ keep='first' : 기본값, 가장 먼저 등장한 데이터만 남기고 나머지는 삭제
➡️ keep='last': 가장 나중에 등장한(마지막에 있는) 데이터만 남기고 나머지는 삭제
➡️ keep=False: 중복된 데이터는 그냥 싹 다 지움
💡 sort_values('PatientID')
- 해석: PatientID(환자 번호)를 기준으로 데이터를 오름차순으로 정렬
- 중복을 제거한 직후에는 데이터 순서가 듬성듬성할 수 있기 때문
💡.reset_index(drop=True)
- 정렬을 하거나 행을 삭제하면 왼쪽의 인덱스(0, 1, 2...) 번호가 5, 2, 10... 처럼 꼬일 수 있어서 0, 1, 2... 순서로 초기화
💡drop=True
- 인덱스를 새로 만들 때, 기존에 꼬여있던 인덱스 번호를 완전히 삭제
- 이걸 안 쓰면 기존 인덱스가 'index'라는 새로운 컬럼으로 들어와서 표가 지저분해짐.

💡비트 연산자(Bitwise Operators)
- AND (&) / OR (|) / NOT (~)
- 판다스(Pandas)나 넘파이(Numpy)에서 데이터를 필터링할 때 사용
‼️ 판다스 조건문에서 이 기호들을 쓸 때는 반드시 소괄호 ( )로 각 조건을 감싸줘야 합니다.
예) df[df.Age > 30 & df.BMI > 25] → 에러!!!
예) df[(df.Age > 30) & (df.BMI > 25)] →(O)
df_processed.loc[outliers_condition, 'BloodPressure'] = bp_median
1️⃣ df_processed.loc[행조건, 열이름] : 특정 위치 선택
2️⃣ = bp_median : 선택된 위치 값들을 전부 중앙값으로 바꿔라


솔직히 과제를 보고 눈물날 뻔했다. 😔
공부량은 매일 늘어나고 제대로 공부하고 있는건지 의심이 되서 너무 속상했다.
그래서 과제를 포기할까 생각했지만...
답지를 보면서 GPT랑 제미나이를 통해 문장 하나하나 전부 해석해봤다.
그래도 개념을 이해하고 코드를 보니 재밌데 느껴지기는 해서 다행이었다.
그래도 스스로에게 칭찬을 좀 해보자면 IQR 개념은 제대로 기억하고 있어서
많이 부족했어도 수고했다고 말해주고 싶다!