1. 그룹화 및 Aggregation


< 🎯퀴즈 >

# titanic_df 데이터 사용
titanic_df.groupby('Embarked')['Survived'].mean()
>>> 값이 0, 1로만 이루어져 있어서 평균값은 생존자 비율과 같다.

# 객실등급(Pclass)별 최고령 승객의 나이(Age)
titanic_df.groupby('Pclass')['Age'].max()

2. 문자열 처리
문자열 데이터 처리는 매우 중요. Series.str ➡️ df['컬럼'].str.매서드( ) 형식으로 사용
▶ 대소문자 변환: .lower(), .upper(), .capitalize(), .title() 등
▶ 공백 제거: .strip() (문자열 양 끝 공백 제거), .lstrip(), .rstrip()
▶ 길이 계산: .len() 각 문자열의 길이 반환
▶ 검색/포함 여부: .contains("문자열") 부분 문자열 포함 여부 (True/False 시리즈 반환), .startswith(), .endswith()
▶ 치환: .replace("기존", "새로운") 문자열 치환 (정규표현식 사용 가능)
▶ 분할: .split("구분자") 구분자를 기준으로 문자열을 나누어 리스트로 반환; 이후 [index]로 각 부분 추출 가능
▶ 이 외에도 .find(), .isdigit(), .join() 등 다양한 메서드 활용 가능
🚨 주의: Series.str 메서드는 NaN (결측치)가 있으면 작업이 불가능하므로, 먼저 결측치를 처리하거나 제거해야 함.
< 🎯퀴즈 >

# 문자열을 , 구분으로 나누고 인덱스 1 ➡️ . 구분으로 나누고 인덱스 0
titanic_df['name_title'] = titanic_df['Name'].str.split(',').str[1].str.split('.').str[0]
titanic_df['name_title']

# Embarked 값(S, C, Q)을 모두 소문자로!
titanic_df['Embarked'] = titanic_df['Embarked'].str.lower()
# Embarked 열 고유값 추출
titanic_df['Embarked'].unique()
3. 시간 데이터 처리

< 🎯 예제 >

# 최초 탑승시각 이후 얼마나 후에 탑승했는지 계산
titanic_df['hour_after_boarding'] = titanic_df['BoardTime'] - titanic_df['BoardTime'].min()
titanic_df['hour_after_boarding']
>>> 출력:
---------------------
0 0 days 00:00:00
1 0 days 06:00:00
2 0 days 00:00:00
3 0 days 00:00:00
4 0 days 00:00:00
...
----------------------
Name: hour_after_boarding, Length: 891, dtype: timedelta64[ns]
# 시간(hour) 단위로 변환 🚨
titanic_df['hour_after_boarding'] = titanic_df['hour_after_boarding'].dt.total_seconds()/3600
# 보기좋게 출력
titanic_df[['Embarked', 'BoardTime', 'hour_after_boarding']].head()
>>> 출력:
-------------------------------------------
Embarked BoardTime hour_after_boarding
0 s 1912-04-10 12:00:00 0.0
1 c 1912-04-10 18:00:00 6.0
2 s 1912-04-10 12:00:00 0.0
3 s 1912-04-10 12:00:00 0.0
4 s 1912-04-10 12:00:00 0.0
-------------------------------------------
< 🎯 퀴즈 >

# 우선 'BoardHour'열이 datetime 형식 확인 후, .dt.hour 사용하여 시간 추출
titanic_df['BoardHour'] = titanic_df['BoardTime'].dt.hour
# 보기좋게 출력
titanic_df[['BoardHour','BoardTime', 'hour_after_boarding']].head()
>>> 출력:
----------------------------------------------------
BoardHour BoardTime hour_after_boarding
0 12.0 1912-04-10 12:00:00 0.0
1 18.0 1912-04-10 18:00:00 6.0
2 12.0 1912-04-10 12:00:00 0.0
3 12.0 1912-04-10 12:00:00 0.0
4 12.0 1912-04-10 12:00:00 0.0
----------------------------------------------------
🚨 생각보다 시간 데이터 처리하는 게 쉽지는 않은 것 같다. 꼼꼼히 학습해두고 자주 보자!!🚨
4. 데이터 결합 기법

< 🎯 예제 >

#1. 항구 코드 -> 이름 대응되는 새로운 데이터프레임 생성
df = pd.DataFrame({
'Embarked' : ['s', 'c', 'q'],
'PortName': ['Southampton', 'Cherbourg', 'Queenstown']
})
#2. Embarked 열 기준 병합
add_portname = pd.merge(titanic_df, df, on='Embarked', how='left'
add_portname[['Embarked', 'PortName']].head()
>>> 출력:
---------------------------------
Embarked PortName
0 s Southampton
1 c Cherbourg
2 s Southampton
3 s Southampton
4 s Southampton
---------------------------------
< 🎯 퀴즈 >

# 퀴즈 1 정답: df1과 df2를 ID 열 기준으로 병합
merged_df = pd.merge(df1, df2, on='ID', how='inner') # how는 필요에 따라 'left', 'right', 'outer' 등 변경
print("병합 결과:\n", merged_df)
# 퀴즈 2 정답: df1과 df2 세로 연결
concatenated_df = pd.concat([df1, df2], axis=0, ignore_index=True)
print("세로 연결 결과:\n", concatenated_df)
5. map / apply / lambda 함수 활용
💡 반복적인 데이터 처리를 위해 apply와 map 매서드, 그리고 lambda 함수를 활용한다!




< 🎯예제 >

#예제1: map을 사용한 값 치환
titanic_df['mapping_sur'] = titanic_df['Survived'].map({0:'사망', 1:'생존'})
titanic_df[['Survived', 'mapping_sur']].head()
>>> 출력:
------------------------
Survived mapping_sur
0 0 사망
1 1 생존
2 1 생존
3 1 생존
4 0 사망
------------------------
#예제2: apply와 lambda를 사용한 나이대 분류
titanic_df['AgeGroup']= titanic_df['Age'].apply(lambda x: '미성년자' if x < 18 else '성인')
titanic_df[['Age', 'AgeGroup']].head()
>>> 출력:
-----------------
Age AgeGroup
0 22.0 성인
1 38.0 성인
2 26.0 성인
3 35.0 성인
4 35.0 성인
-----------------
#예제3: DataFrame.apply를 사용한 가족 규모 계산
titanic_df[['SibSp', 'Parch']].head() # 기존 수 확인!
FamilySize = titanic_df.apply(lambda row: row['SibSp'] + row['Parch'] + 1, axis=1)
titanic_df['FamilySize'] = FamilySize
titanic_df[['SibSp', 'Parch', 'FamilySize']].head()
>>> 출력:
--------------------------------------
SibSp Parch FamilySize
0 1 0 2
1 1 0 2
2 0 0 1
3 1 0 2
4 0 0 1
--------------------------------------
< 🎯 퀴즈 >

titanic_df['Pclasslabel'] = titanic_df['Pclass'].map({1:'1등석',2:'2등석', 3:'3등석'})
titanic_df[['Pclass', 'Pclasslabel']].head()

# 방법1 : lambda 활용
titanic_df['NameLength'] = titanic_df['Name'].apply(lambda x: len(x))
titanic_df[['Name', 'NameLength']]
# 방법2 : 문자열 기능
titanic_df['namelength'] = titanic_df['Name'].str.len()
titanic_df[['Name', 'namelength']].head()
>>> 출력:
--------------------------------------------------------------------
Name namelength
0 Braund, Mr. Owen Harris 23
1 Cumings, Mrs. John Bradley (Florence Briggs Th... 51
2 Heikkinen, Miss. Laina 22
3 Futrelle, Mrs. Jacques Heath (Lily May Peel) 44
4 Allen, Mr. William Henry 24
--------------------------------------------------------------------
끝.