문제 2.
Seaborn 라이브러리에서 제공하는 Penguins 데이터셋을 활용하여 다음을 수행하세요:
1) Penguins 데이터셋을 불러옵니다.
2) bill_length_mm이 species별 bill_length_mm의 평균(”mean_bill_length”)보다 작은 데이터를 선택하세요.
3) 선택된 데이터에 새 열을 추가하여, bill_length_mm과 bill_depth_mm을 조합하여 다음과 같은 규칙으로 계산한 값을 저장하세요:
- bill_length_mm * 0.5 + bill_depth_mm * 0.3 새 열의 이름은 weighted_bill로 지정하세요.
4) weighted_bill이 25 이상인 행만 추가로 필터링하여 출력하세요.
5) species 값의 문자열 길이가 6보다 크면 "long", 6 이하면 "short"으로 분류하는 새 열을 추가하세요. 새 열의 이름은 species_length_category로 지정하세요.
- 힌트:
- groupby를 사용하여, species별 bill_length_mm의 평균 데이터 프레임을 생성하여 merge하거나, 다음 transform 함수를 사용할 수 있습니다. https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.transform.html
- apply()와 lambda를 사용하여 조건에 따른 새 열을 생성할 수 있습니다.
- 결과: final_result
'species', 'island', 'bill_length_mm', 'bill_depth_mm',
'flipper_length_mm', 'body_mass_g', 'sex', 'mean_bill_length',
'weighted_bill', 'species_length_category'
- 10번째, 90번째 행을 출력하세요
- skeleton code
# 1) Penguins 데이터셋 로드
penguins = sns.load_dataset("penguins")
"""
코드 입력
"""
# 결과 출력
print(final_result.iloc[10])
print(final_result.iloc[90])
출력 결과 예시
'''
species Chinstrap
island Dream
bill_length_mm 45.9
bill_depth_mm 17.1
flipper_length_mm 190.0
body_mass_g 3575.0
sex Female
mean_bill_length 48.833824
weighted_bill 28.08
species_length_category long
Name: 166, dtype: object
species Gentoo
island Biscoe
bill_length_mm 41.7
bill_depth_mm 14.7
flipper_length_mm 210.0
body_mass_g 4700.0
sex Female
mean_bill_length 47.504878
weighted_bill 25.26
species_length_category short
Name: 326, dtype: object
'''
💡 문제 풀이
`내 풀이`
import seaborn as sns
# 1) Penguins 데이터셋 로드
penguins = sns.load_dataset("penguins")
# 2) bill_length_mm이 species별 bill_length_mm의 평균(”mean_bill_length”)보다 작은 데이터를 선택하세요.
avg_bill_length = penguins.groupby('species')['bill_length_mm'].mean().reset_index()
avg_bill_length.rename(columns={'bill_length_mm':'avg_bill_length'},inplace=True)
penguins_merged = pd.merge(penguins, avg_bill_length, how='left', on='species')
penguins_small = penguins_merged[penguins_merged.bill_length_mm < penguins_merged.avg_bill_length]
# 3) 선택된 데이터에 새 열 weighted_bill을 추가하여, bill_length_mm * 0.5 + bill_depth_mm * 0.3로 지정하세요.
penguins_small['weighted_bill'] = (penguins_small['bill_length_mm'] * 0.5) + (penguins_small['bill_depth_mm'] * 0.3)
# 4) weighted_bill이 25 이상인 행만 추가로 필터링하여 출력하세요.
final_result = penguins_small[penguins_small.weighted_bill >= 25]
# 5) species 값의 문자열 길이가 6보다 크면 "long", 6 이하면 "short"으로 분류하는 새 열을 추가하세요. 새 열의 이름은 species_length_category로 지정하세요.
final_result['species_length_category'] = final_result['species'].apply(lambda x: 'long' if len(x)>6 else 'short')
# 결과 출력
print(final_result.iloc[10])
print(final_result.iloc[90])
`오답노트`
- 참고) 나는 평균보다 작은 값만 추출할 때 merge를 사용했는데 또 다른 풀이로는 transform 사용할 수도 있었음
- `apply(lambda)` df['기준 컬럼'].apply(lambda x: 값1 if 조건 else 값2)
- 기준 컬럼에서 조건에 해당하면 값1, 아니라면 값2를 더해서 pd.Series 형태로 반환함
`또 다른 풀이`
import seaborn as sns
# 1) Penguins 데이터셋 로드
penguins = sns.load_dataset("penguins")
# 2) 'species'별 평균 bill_length_mm 계산 및 조건 필터링
penguins["mean_bill_length"] = penguins.groupby("species")["bill_length_mm"].transform("mean")
filtered_penguins = penguins[penguins["bill_length_mm"] < penguins["mean_bill_length"]]
# 3) 새 열 추가: bill_length_mm과 bill_depth_mm의 가중합 계산
filtered_penguins["weighted_bill"] = filtered_penguins["bill_length_mm"] * 0.5 + filtered_penguins["bill_depth_mm"] * 0.3
# 4) weighted_bill이 25 이상인 행 필터링
final_result = filtered_penguins[filtered_penguins["weighted_bill"] >= 25]
# 5) species 문자열 길이를 기준으로 분류
final_result["species_length_category"] = final_result["species"].apply(
lambda x: "long" if len(x) > 6 else "short"
)
print(final_result.iloc[10])
print(final_result.iloc[90])
- 평균보다 작은 값만 추출할 때 transform 함수 사용
- `transform함수`
- groupby와 함께 써서 merge없이도 집계한 값을 간단하게 데이터프레임에 추가할 수 있음
- 필터링할 때도 쓸 수 있음
- ex. penguins[penguins.groupby("species")["bill_length_mm"].transform("mean")>39] # 종별 평균이 39이상인 것만 추출