Lambda 함수(익명 함수) 쉽게 기억하는 방법
Lambda 함수는 "이름 없는 짧은 함수" 라고 생각하면 이해하기 쉽습니다.
1. 기본 문법
- lambda : 함수 선언 키워드
- 매개변수 : 입력값 (여러 개도 가능)
- 표현식 : 반환할 값 (한 줄로 작성해야 함)
기본 함수와 비교하면 이렇게 정리할 수 있어요.
✔ lambda는 return 없이도 결과를 반환합니다.
2. 사용 예시
(1) 리스트 정렬에 사용
🔹 lambda x: x[1] → 튜플에서 두 번째 값을 기준으로 정렬
(2) map(), filter(), reduce()와 함께 사용
map() : 리스트의 각 요소를 변환
🔹 map(함수, 리스트) → 리스트의 각 요소에 함수 적용
filter() : 특정 조건을 만족하는 값만 필터링
🔹 filter(조건, 리스트) → 조건에 맞는 값만 남김
reduce() : 누적 연산 (functools 필요)
🔹 reduce(함수, 리스트) → 리스트 요소를 누적해서 연산
3. Lambda 함수 쉽게 기억하는 법
"한 줄 함수"
- 작은 기능을 간단하게 정의할 때 사용
- return 없이 바로 값 반환
- 반드시 한 줄로 작성!
- 기본 함수랑 비교해 보면서 익히기!
- map, filter, sort에서 자주 활용됨!
Lambda 함수 핵심 요약
특징/설명
함수 이름 없음 | 익명 함수(변수에 할당 가능) |
한 줄로 작성 | return 없이 바로 값 반환 |
map, filter, sort와 자주 사용 | 리스트 변환, 필터링, 정렬 등에 활용 |
# 라이브러리 불러오기
import seaborn as sns # sns라는 별칭(alias)을 사용해 seaborn을 간단하게 호출 가능
import pandas as pd # pd라는 별칭을 사용해 pandas 함수를 간단하게 호출 가능
# titanic 데이터셋에서 age, fare 2개 열을 선택하여 데이터프레임 만들기
titanic = sns.load_dataset('titanic') # 타이타닉호 승객 정보 (나이, 성별, 생존 여부 등 포함)
# seaborn에 내장된 타이타닉 데이터셋을 불러옴, 데이터는 데이터프레임(Pandas DataFrame) 형태로 저장됨
df = titanic.loc[:, ['age','fare']]
# 데이터프레임에서 특정 열만 선택하여 새로운 데이터프레임 생성,
- titanic.loc[:, ['age', 'fare']]
- loc[] : 라벨(컬럼명) 기반으로 데이터 선택
- : : 모든 행을 선택
- ['age', 'fare'] : "age"와 "fare" 열만 선택
🔹 df에는 승객의 나이(age)와 요금(fare) 정보만 포함됨
df.head() # 데이터프레임의 상위 5개 행을 출력, 데이터 확인용 (5개 기본, df.head(10) → 10개 출력 가능)
코드 흐름 : 1️⃣ Seaborn과 Pandas 라이브러리를 불러온다. 2️⃣ Seaborn의 타이타닉 데이터를 데이터프레임으로 가져온다. 3️⃣ age(나이)와 fare(요금) 열만 선택하여 새로운 데이터프레임 생성. 4️⃣ .head()를 사용해 데이터 일부를 확인한다
# 라이브러리 불러오기
import seaborn as sns
import pandas as pd
# titanic 데이터셋에서 age, fare 2개 열을 선택하여 데이터프레임 만들기
titanic = sns.load_dataset('titanic')
df = titanic.loc[:, ['age','fare']]
df.head()
결과값
# 시리즈 객체에 적용
sr1 = df['age'].apply(add_10)
sr1.head()
# 람다 함수 활용: 시리즈 객체에 적용
sr2 = df['age'].apply(lambda n: n + 10)
sr2.head() 이상으로 해도 결과값은 동일하다.
# 함수의 매개변수가 2개 이상인 경우 (예: 시리즈 + 숫자)
sr3 = df['age'].apply(add_two_obj, b=10)
sr3.head() 이상으로 해도 결과값은 동일하다.
# 함수의 매개변수가 2개 이상인 경우 (람다 함수 활용)
sr4 = df['age'].apply(lambda a, b: a + b, b=10)
sr4.head() 이상으로 해도 결과값은 동일하다.
# 시리즈 객체에 함수를 적용
def over_thirty(age):
return age > 30 # 나이가 30보다 크면 True, 작거나 같으면 False
sr_map = df['age'].map(over_thirty)
sr_map.head()
# titanic 데이터의 성별 데이터의 고유값
print(titanic['sex'].unique())
print(titanic['sex'].head())
# 딕셔너리 정의하여 값을 변환 (문자열 -> 정수)
over_forty_dict = {'male': 0, 'female':1}
titanic['gender'] = titanic['sex'].map(over_forty_dict)
print(titanic['gender'].head())
"타이타닉 데이터의 'sex' 열을 숫자로 변환하여 새로운 'gender' 열을 생성하는 과정"
✔ 딕셔너리 + map()을 활용하면 문자열 데이터를 숫자로 쉽게 변환 가능!
✔ 머신러닝 등 숫자 기반 분석을 위해 필수적인 데이터 전처리 기법!
# 각 열에 대해 최대값, 최소값, 평균, 중간값을 계산하는 함수
def calculate_stats(col):
max_val = col.max()
min_val = col.min()
mean_val = col.mean()
median_val = col.median()
# 새로운 시리즈 반환
return pd.Series([max_val, min_val, mean_val, median_val], index=['Max', 'Min', 'Mean', 'Median'])
# 각 열에 calculate_stats 함수 적용 (데이터프레임을 반환)
result_df = df.apply(calculate_stats, axis=0)
result_df
지표Age (나이)Fare (요금)
Mean (평균) | 29.70 | 32.20 |
Median (중간값) | 28.00 | 14.45 |
차이점
- Age(나이)
- 평균(29.70)과 중간값(28.00)이 크게 차이 나지 않음 → 극단적인 나이가 적음
- Fare(요금)
- 평균(32.20)과 중간값(14.45)의 차이가 큼 → 비싼 요금(예: 512.33)이 평균을 올림!
✔ 즉, Fare(요금) 데이터는 극단적인 값(비싼 요금)이 많아서 평균이 크게 영향을 받음!
✔ Median(중간값)은 이상치에 영향을 덜 받으므로, 데이터의 대표성을 가지는 경우가 많음!
평균(Mean)은 이상치의 영향을 많이 받고, 중간값(Median)은 영향을 적게 받는다!
✔ 극단적인 값이 많은 경우 → Median(중간값) 활용
✔ 데이터가 고르게 분포하면 → Mean(평균) 사용
# 각 행에 대해 최대값과 최소값의 차이와 평균을 계산하는 함수
def calculate_diff_avg(row):
diff = row.max() - row.min()
avg = row.mean()
# 새로운 시리즈 반환
return pd.Series([diff, avg], index=['차이', '평균'])
# apply 함수를 사용하여 각 행에 calculate_diff_avg 함수 적용
result_df2 = df.apply(calculate_diff_avg, axis=1)
result_df2
"각 행에서 최대값과 최소값의 차이를 구하고, 평균을 계산하여 새로운 데이터프레임 생성"
✔ 행 단위(axis=1)로 계산을 적용하는 대표적인 예시!
✔ 최대-최소 차이(차이)는 데이터 분포를 파악하는 데 유용!
# 람다 함수를 사용하여 각 행에 대해 계산 적용 (multiplier 매개변수를 추가)
result_df3 = df.apply(lambda row, multiplier: pd.Series([(row.max() - row.min()) * multiplier, row.mean()],
index=['차이', '평균']),
multiplier = 2, axis=1)
result_df3
위와 아래 의 차이점은 "람다 함수 코드는 multiplier 매개변수를 추가하여 차이값을 원하는 배율로 조정할 수 있다!"
✔ 단순한 경우 → 람다 함수 사용이 편리
✔ 복잡한 경우 → 별도 함수(def)를 사용하는 것이 더 가독성이 좋음!
# 평균값이 30을 초과하는 열만 필터링
filtered_columns = df.apply(lambda x: x.mean() > 30)
print(filtered_columns, "\n")
# 필터링된 열을 기반으로 새로운 데이터프레임 생성
filtered_df = df.loc[:, filtered_columns]
filtered_df
각 열의 평균값을 확인하고, 평균이 30을 초과하는 열만 선택하여 새로운 데이터프레임을 만든다!"
✔ apply()와 lambda를 활용하여 조건부 필터링 가능!
✔ 필터링된 열만 선택할 때 df.loc[:, 조건] 패턴을 활용하면 효과적!
# 각 행의 평균값이 50을 초과하는지 여부에 따라 'High' 열 추가
df['High'] = df.apply(lambda row: 'Yes' if row.mean() > 50 else 'No', axis=1)
df
apply(axis=1)를 사용하여 행 단위로 조건 적용 가능!
✔ 데이터프레임에 새로운 조건부 컬럼을 추가할 때 유용한 기법!
# 라이브러리 불러오기
import seaborn as sns
import pandas as pd
# titanic 데이터셋에서 age, fare 2개 열을 선택하여 데이터프레임 만들기
titanic = sns.load_dataset('titanic')
df1 = titanic.loc[:, ['age','fare']]
df2 = titanic.loc[:, ['embark_town','embarked']]
# 각 열의 NaN 찾기 - 데이터프레임 전달하면 데이터프레임을 반환
def missing_value(df):
return df.isnull()
# 데이터프레임에 pipe() 메소드로 함수 매핑
result_df = df1.pipe(missing_value) # pipe()를 사용하면 여러 개의 함수 적용을 쉽게 연결(체이닝)할 수 있음!
result_df
"타이타닉 데이터에서 'age'와 'fare' 열을 선택하고, 결측값 여부를 파악하여 새로운 데이터프레임을 생성한다!" 🚀
✔ isnull()을 활용해 결측값 확인 가능!
✔ pipe()를 사용하면 여러 개의 데이터 처리 과정을 연결해서 쉽게 작성 가능!
# 각 열의 NaN 개수 반환 - 데이터프레임 전달하면 시리즈 반환
def missing_count(df): #
return missing_value(df).sum()
result_series = df1.pipe(missing_count)
result_series
age 177
fare 0
dtype: int64
각 열의 결측값(NaN) 개수를 계산하여 시리즈 형태로 반환한다!"
✔ .isnull().sum()을 활용하면 NaN 개수를 쉽게 구할 수 있음!
✔ pipe()를 사용하면 여러 개의 데이터 처리 과정을 체이닝(여러 개의 연산을 한 줄로 이어서 실행하는 기법) 하여 깔끔하게 작성 가능!
def extract_initial(df):
df['town_initial'] = df['embark_town'].str[0]
return df
def verify_initial(df):
df['verified'] = df['embarked'] == df['town_initial']
return df
verify_initial(extract_initial(df2))
embark_town / embarked / town_initial / verified
Southampton | S | S | True |
Cherbourg | C | C | True |
Southampton | S | S | True |
Southampton | S | S | True |
Southampton | S | S | True |
... | ... | ... | ... |
Southampton | S | S | True |
Southampton | S | S | True |
Southampton | S | S | True |
Cherbourg | C | C | True |
Queenstown | Q | Q | True |
891 rows × 4 columns
"embark_town의 첫 글자를 추출하여 embarked 값과 비교, 일치 여부를 verified 열에 저장한다!" 🚀
✔ str[0]을 사용하여 문자열의 첫 글자 추출 가능!
✔ 비교 연산(==)을 활용하여 True/False 값 생성 가능!
✔ 데이터 전처리 과정에서 유용한 검증 기법!
# chain method - pipe 활용
df2.pipe(extract_initial).pipe(verify_initial)
embark_town / embarked / town_initial / verified
Southampton | S | S | True |
Cherbourg | C | C | True |
Southampton | S | S | True |
Southampton | S | S | True |
Southampton | S | S | True |
... | ... | ... | ... |
Southampton | S | S | True |
Southampton | S | S | True |
Southampton | S | S | True |
Cherbourg | C | C | True |
Queenstown | Q | Q | True |
891 rows × 4 columns
"embark_town의 첫 글자를 town_initial로 추출하고, embarked 값과 비교하여 verified 열을 추가한다!"
✔ 데이터 변환 작업을 체이닝 방식(pipe())으로 깔끔하게 연결 가능!
✔ 여러 개의 변형 과정을 한 줄로 쉽게 적용할 수 있음!
# 라이브러리 불러오기
import seaborn as sns
import pandas as pd
# titanic 데이터셋의 부분을 선택하여 데이터프레임 만들기
titanic = sns.load_dataset('titanic')
df = titanic.loc[:, 'survived':'age'] # loc[:, 'start':'end'] → 연속된 열 선택 가능!
df.head()
survived/pclass/sex/age
0 | 3 | male | 22.0 |
1 | 1 | female | 38.0 |
1 | 3 | female | 26.0 |
1 | 1 | female | 35.0 |
0 | 3 | male | 35.0 |
# 열 이름의 리스트 만들기
columns = list(df.columns.values)
# .values를 사용하여 NumPy 배열을 Python 리스트로 변환, .values 없이도 동일한 결과를 얻을 수 있음!
print(columns)
['survived', 'pclass', 'sex', 'age']
df.columns → 열 이름 가져오기
✔ list(df.columns) → 리스트로 변환
✔ 데이터 분석 시 열 이름을 리스트로 저장해 활용 가능
# 열 이름을 알파벳 순으로 정렬하기
columns_sorted = sorted(columns, reverse=False)
# sorted(columns) → 리스트 columns를 알파벳 순으로 정렬, ✔ reverse=False → 오름차순(기본값)으로 정렬
df_sorted = df[columns_sorted]
df_sorted.head()
"데이터프레임의 열 이름을 알파벳 순으로 정렬하여 새로운 데이터프레임을 만든다!"
✔ sorted(columns) → 열 이름 정렬 가능!
✔ df[columns_sorted] → 정렬된 순서로 열을 재배치!
✔ 데이터 분석 전 열 정리가 필요할 때 유용!
age / pclass / sex / survived
22.0 | 3 | male | 0 |
38.0 | 1 | female | 1 |
26.0 | 3 | female | 1 |
35.0 | 1 | female | 1 |
35.0 | 3 | male | 0 |
# 열 이름을 사용자가 정의한 임의의 순서로 재배치하기
columns_customed = ['pclass', 'sex', 'age', 'survived']
df_customed = df[columns_customed]
df_customed.head()
"데이터프레임의 열을 사용자가 원하는 임의의 순서로 재배치한다!"
✔ df[['열1', '열2', ...]] → 원하는 순서로 열 선택 가능!
✔ 데이터 정리 및 가독성을 높일 때 유용!
# 라이브러리 불러오기
import pandas as pd
# 데이터셋 가져오기
df = pd.read_excel('./data/주가데이터.xlsx', engine= 'openpyxl')
# 엑셀 파일을 읽을 때는 openpyxl을 반드시 설치해야 함. ✔ CSV 파일(.csv)은 pd.read_csv()로 바로 읽을 수 있음
df.head()
# 연, 월, 일 데이터 분리하기
df['연월일'] = df['연월일'].astype('str') # 문자열 메소드 사용을 자료형 변경
dates = df['연월일'].str.split('-')
# 문자열을 split() 메서드로 분리, 날짜 형식이 'YYYY-MM-DD' 같은 문자열이면 str.split('-')로 쉽게 분리 가능!
dates.head()
0 [2018, 07, 02]
1 [2018, 06, 29]
2 [2018, 06, 28]
3 [2018, 06, 27]
4 [2018, 06, 26]
Name: 연월일, dtype: object
# 분리된 정보를 각각 새로운 열에 담아서 df에 추가하기
df['연'] = dates.str.get(0) # dates 변수의 원소 리스트의 0번째 인덱스 값
df['월'] = dates.str.get(1) # dates 변수의 원소 리스트의 1번째 인덱스 값
df['일'] = dates.str.get(2) # dates 변수의 원소 리스트의 2번째 인덱스 값
df.head()
"날짜 데이터를 연, 월, 일로 분리하여 새로운 열을 생성한다!"
✔ str.get(index) → 리스트에서 특정 위치 값 추출 가능!
✔ 날짜 분석, 시계열 데이터 전처리 시 매우 유용
# expand 옵션
df_expand = df['연월일'].str.split('-', expand=True)
df_expand.head()
✔ str.split('-', expand=True) → 리스트가 아니라 컬럼으로 나누는 핵심 기법!
✔ 날짜 분석, 시계열 데이터 전처리 시 매우 유용!
Pandas의 groupby()를 이용한 데이터 그룹화
# class 열을 기준으로 분할
grouped = df.groupby(['class'], observed=True)
# 'class' 열을 기준으로 데이터를 First, Second, Third 등급별로 나눕니다.
# observed=True 카테고리형(categorical) 데이터에 대해 실제로 존재하는 값만 그룹화
print(grouped)
df.groupby(['class']) → 'class' 열 기준으로 승객 데이터를 First, Second, Third 그룹으로 나눔
print(grouped) → 그룹 객체를 출력하지만 내용은 바로 보이지 않음
grouped.size() → 각 클래스별 승객 수 확인 가능
grouped.mean() → 각 클래스별 나이, 요금, 생존율 평균 확인 가능
# 그룹 객체를 iteration으로 출력: head() 메소드로 첫 5행만을 출력
for key, group in grouped:
print('* key :', key)
print('* number :', len(group))
print(group.head())
print('\n')
- grouped은 groupby()로 그룹화된 데이터이므로, 각 그룹을 반복(iteration)하면서 접근할 수 있습니다.
- key → 그룹의 이름 (예: 'First', 'Second', 'Third')
- group → 해당 그룹에 속한 데이터프레임 (df)
- 즉, grouped을 반복(iterate)하면, 각 그룹별로 데이터가 분리되어 출력
groupby() 객체는 for key, group in grouped: 형태로 반복(iterate)할 수 있음
key → 현재 그룹의 이름 ('First', 'Second', 'Third')
group → 해당 그룹의 데이터프레임
group.head() → 각 그룹에서 상위 5개 행만 출력
# 연산 메소드 적용
average = grouped.mean(numeric_only=True)
average
groupby('class') → 좌석 등급별 그룹화
mean(numeric_only=True) → 수치형 데이터의 평균값 계산
average → First, Second, Third 클래스별 평균 age, fare, survived 값 저장
이제 groupby()와 mean()을 활용해 데이터 분석
1. groupby() 함수란?
groupby() 함수는 데이터를 특정 기준으로 그룹화하여 분석할 때 사용합니다.
SQL의 GROUP BY 구문과 유사하게 동작합니다.
주로 평균(mean()), 합계(sum()), 개수(count()) 등의 집계 연산과 함께 사용
df.groupby('열이름')
- '열이름'을 기준으로 데이터를 그룹화
- 같은 값을 가지는 행들끼리 하나의 그룹으로 묶음
- 반환 값은 GroupBy 객체 (즉시 출력되지 않음)
1-2. groupby()로 여러 개의 열 기준으로 그룹화
df.groupby(['class', 'sex'])
- 각 좌석 등급과 성별에 따른 승객 수를 출력
2. mean() 함수
mean() 함수는 수치형 데이터의 평균을 계산할 때 사용됩니다.
groupby()와 함께 사용하면 각 그룹별 평균값을 구할 수 있음
df.mean(numeric_only=True)
- 각 열의 평균을 계산
- numeric_only=True → 문자열(예: sex, class)을 제외하고 숫자 데이터만 계산
groupby()와 mean() 함께 사용
df.groupby('class').mean(numeric_only=True)
- 'class'별로 그룹화한 후, 각 그룹의 평균값을 계산
- 수치형 데이터(예: age, fare, survived)만 포함됨
groupby('class') → 좌석 등급별 그룹화
groupby(['class', 'sex']) → 좌석 등급 + 성별 그룹화
mean(numeric_only=True) → 그룹별 수치형 데이터의 평균값 계산
grouped.mean()을 실행하면 First, Second, Third 그룹별 평균 나이, 요금, 생존율 등을 분석 가능
# class 열, sex 열을 기준으로 분할
grouped_two = df.groupby(['class', 'sex'], observed=True)
groupby(['class', 'sex']) → 두 개의 열(class, sex)을 기준으로 그룹화
- 'class' → 좌석 등급 (First, Second, Third)
- 'sex' → 성별 (male, female)
- 즉, 총 6개의 그룹이 만들어짐:
- First - male
- First - female
- Second - male
- Second - female
- Third - male
- Third - female
observed=True → 카테고리형(category) 데이터에서 존재하는 값만 그룹화
- 일반적으로 category 타입이 아니면 큰 영향 없음
- 생략해도 동일한 결과
# grouped_two 그룹 객체를 iteration으로 출력
for key, group in grouped_two:
grouped_two는 그룹 객체(GroupBy Object) 이므로, 이를 반복(iteration)하면 각 그룹을 나누어 확인 가능
- key → 현재 그룹의 이름(튜플 형태) (('First', 'male'), ('Third', 'female') 등)
- group → 해당 그룹에 속하는 데이터프레임(DataFrame)
print('* key :', key) # 현재 그룹의 **이름(튜플)**을 출력 예: ('First', 'male'), ('Third', 'female')
print('* number :', len(group)) # 현재 그룹에 속한 데이터 개수(승객 수)를 출력
print(group.head())
print('\n')
# class 열, sex 열을 기준으로 분할
grouped_two = df.groupby(['class', 'sex'], observed=True)
# grouped_two 그룹 객체를 iteration으로 출력
for key, group in grouped_two:
print('* key :', key)
print('* number :', len(group))
print(group.head())
print('\n')
groupby(['class', 'sex']) → 좌석 등급과 성별을 기준으로 그룹화
for key, group in grouped_two: → 그룹별 데이터 반복(iteration) 처리 가능
group.head() → 각 그룹별 상위 5개 행만 출력
결과적으로, First 클래스 여성의 생존율이 가장 높고, Third 클래스 남성의 생존율이 가장 낮음
# 라이브러리 불러오기
import pandas as pd
import seaborn as sns
# titanic 데이터셋에서 age, sex 등 5개 열을 선택하여 데이터프레임 만들기
titanic = sns.load_dataset('titanic')
df = titanic.loc[:, ['age','sex', 'class', 'fare', 'survived']]
# class 열을 기준으로 분할
grouped = df.groupby(['class'], observed=True)
# 각 그룹에 대한 모든 열의 표준편차를 집계하여 데이터프레임으로 반환
std_all = grouped.std(numeric_only=True) # .std(numeric_only=True) → 그룹별 age, fare, survived의 표준편차 계산
std_all
# 그룹 객체에 aggregate() 메소드 적용 (mean 함수를 모든 열에 적용)
agg_mean = grouped.aggregate('mean', numeric_only=True)
# ggregate()는 여러 개의 통계 함수를 적용할 수 있다는 장점이 있음
agg_mean
groupby('class') → 좌석 등급(class)별로 그룹화
aggregate('mean', numeric_only=True) → 모든 수치형 데이터의 평균값 계산
결과: age, fare, survived의 좌석 등급별 평균값 출력
aggregate(['mean', 'max', 'min', 'std']) → 평균, 최댓값, 최솟값, 표준편차 등 다양한 통계 계산 가능
# 그룹 객체에 agg() 메소드 적용 (mean 함수를 모든 열에 적용)
agg_mean2 = grouped.agg('mean', numeric_only=True)
agg_mean2
- .agg()는 .aggregate()의 더 짧은 표현(syntax sugar)
- 둘은 완전히 동일한 기능을 수행
- 어떤 것을 사용해도 무방하지만, 보통 .agg()를 더 많이 사용
즉, agg('mean')과 aggregate('mean')의 결과는 완전히 동일합니다.
agg_multi = grouped.agg({'fare': ['min', 'max', 'mean'], 'age': ['mean', 'std']})
출력 예시
class fare_min fare_max fare_mean age_mean age_std
First | 0.0 | 512.3 | 84.15 | 38.23 | 11.78 |
Second | 0.0 | 73.5 | 20.66 | 29.87 | 10.40 |
Third | 0.0 | 69.5 | 13.67 | 25.14 | 12.46 |
.agg({'fare': ['min', 'max'], 'age': 'mean'}) → 각 열에 대해 다른 통계 함수 적용 가능
fare에는 min, max, age에는 mean을 적용하여 요금과 나이 분석 가능
결과: fare_min, fare_max, age_mean이 포함된 그룹별 요약 데이터 출력
여러 개의 열에 대해 다양한 함수(min, max, mean, std) 적용 가능
# class 열을 기준으로 분할
grouped = df.groupby(['class'], observed=True)
# fare 열을 그룹별로 누적 합산
grouped['fare'].cumsum()
- fare 열을 그룹별(class)로 나누어 각 그룹 내에서 누적 합산을 계산
- cumsum() → 누적 합(Cumulative Sum)을 계산하는 함수
동작 방식:
- groupby('class')로 좌석 등급별 그룹화
- 각 그룹 내에서 fare 값을 위에서부터 차례로 더함
- 누적된 fare 값을 반환하여 새로운 열로 제공
0 7.2500
1 71.2833
2 15.1750
3 124.3833
4 23.2250
...
886 3801.8417
887 18147.4125
888 6706.9451
889 18177.4125
890 6714.6951
Name: fare, Length: 891, dtype: float64
.groupby('class') → 좌석 등급별로 데이터를 그룹화
.cumsum() → 각 그룹 내에서 누적 합을 계산
결과: fare 값이 각 클래스별로 독립적으로 누적 합산됨
새로운 컬럼으로 추가하여 데이터 분석을 쉽게 수행 가능
그래프로 시각화하여 각 클래스별 요금 증가 추이를 확인 가능
이제 groupby()와 cumsum()을 활용하여 데이터의 누적 변화를 쉽게 분석
# 데이터 개수가 200개 이상인 그룹만을 필터링하여 데이터프레임으로 반환
grouped_filter = grouped.filter(lambda x: len(x) >= 200)
grouped_filter
- filter()를 사용하여 각 그룹의 데이터 개수를 확인하고 조건을 만족하는 그룹만 남김
- lambda x: len(x) >= 200
- x → 개별 그룹 (예: First, Second, Third 클래스)
- len(x) → 해당 그룹의 데이터 개수
- 데이터 개수가 200개 이상이면 유지, 그렇지 않으면 제거
.groupby().filter(lambda x: len(x) >= 200) → 데이터 개수가 200개 이상인 그룹만 유지
결과: First(216명), Third(491명) 클래스만 남고 Second(184명)는 제거됨
필터링 조건을 변경하여 다양한 데이터 분석 가능
# 라이브러리 불러오기
import pandas as pd
import seaborn as sns
# titanic 데이터셋에서 age, sex 등 5개 열을 선택하여 데이터프레임 만들기
titanic = sns.load_dataset('titanic')
df = titanic.loc[:, ['age','sex', 'class', 'fare', 'survived']]
# class 열을 기준으로 분할
grouped = df.groupby(['class'], observed=True)
# 집계 : 각 그룹별 요약 통계정보를 집계
agg_grouped = grouped[['age', 'survived']].apply(lambda x: x.describe())
- groupby(['class'])를 이용하여 좌석 등급별 그룹화
- apply(lambda x: x.describe()) → 각 그룹에 대해 describe() 함수 적용
- age와 survived 열에 대해 기본적인 통계 요약 정보(평균, 표준편차, 최소값, 최대값 등) 제공
agg_grouped
- 각 클래스별(First, Second, Third)로 age와 survived의 통계 요약 제공
- count: 데이터 개수
- mean: 평균값
- std: 표준편차
- min: 최솟값
- 25%, 50%, 75%: 사분위수(퍼센트 기준)
- max: 최댓값
즉, apply(lambda x: x.describe())를 사용하면 각 그룹별 요약 통계를 자동으로 계산 가능.
# 변환: z-score 계산
def z_score(x):
return (x - x.mean()) / x.std()
age_zscore = grouped[['age', 'survived']].apply(z_score)
age_zscore
Z-score (표준화 점수)
- 데이터가 평균에서 얼마나 떨어져 있는지를 나타내는 값
- 단위가 없어서 데이터 간 비교가 용이함
- 계산 공식: Z=X−평균표준편차Z = \frac{X - \text{평균}}{\text{표준편차}}
- Z-score 값의 의미
- 0 → 평균과 동일
- + 값 → 평균보다 큼
- - 값 → 평균보다 작음
z_score() 함수 정의
- x.mean() → 그룹 내 평균 계산
- x.std() → 그룹 내 표준편차 계산
- (x - x.mean()) / x.std() → 각 값의 Z-score를 계산하여 반환
즉, z_score()는 각 그룹에서 age와 survived 값을 표준화하는 함수!
- groupby(['class'])로 좌석 등급별 그룹화
- apply(z_score)를 사용하여 각 그룹에서 age, survived 값을 Z-score로 변환
- 각 그룹의 평균을 0, 표준편차를 1로 변환하여 표준화
Z-score 변환: 평균을 0, 표준편차를 1로 맞추어 표준화
z_score() 함수: (x - x.mean()) / x.std()를 사용하여 그룹별 표준화
apply(z_score) 적용: 그룹별로 age와 survived 열을 변환
결과: 각 그룹에서 표준화된 값으로 변환되어 비교 가능
# 멀티인덱스 정렬
gdf.sort_index(level='sex', ascending=False)
- sort_index() → 인덱스를 기준으로 정렬
- level='sex' → 멀티인덱스(MultiIndex)에서 'sex' 레벨 기준으로 정렬
- ascending=False → 내림차순(여성 → 남성)으로 정렬
sort_index(level='sex') → 멀티인덱스에서 'sex' 레벨을 기준으로 정렬
ascending=False → 내림차순(female → male) 정렬
멀티인덱스 구조에서 특정 레벨을 기준으로 정렬할 때 유용함
이제 멀티인덱스에서 원하는 기준으로 정렬하는 방법을 쉽게 이해할 수 있다!
'데이터 분석가:Applied Data Analytics > 판다스 데이터분석' 카테고리의 다른 글
4. Data transformation - 영국시장의 중고 자동차 가격 데이터 다루기[프로젝트] (0) | 2025.02.13 |
---|---|
3. Data transformation (0) | 2025.02.12 |
1. Data cleaning - 타이타닉 데이터 다루기 (0) | 2025.02.11 |
6장_데이터프레임의 다양한 응용(데이터프레임 합치기) (0) | 2025.02.10 |
Matplotlib (1) | 2025.02.07 |