[전처리/시각화] 개인과제 문제7번 : 부모 학력 수준별 고득점 비율(%) 계산 & 단일 막대 그래프로 나타내기

문제 설명

세 과목(수학, 읽기, 쓰기)이 모두 80점 이상인 “고득점자” 비율을 부모 학력 수준별로 계산해 비교합니다.

단순 평균이 아니라 비율(= 고득점자 수 / 전체 수 × 100)을 계산해야 하므로, 그룹별 분모·분자를 정확히 맞춰 계산하는 것이 핵심입니다.

필요 지식

  • 불리언 필터(다중 조건 AND)
  • groupby(...).size()로 그룹별 건수 계산
  • 인덱스 정렬·정렬 순서 유지(reindex)
  • Series 간 연산으로 비율 계산, fillna(0), 반올림
  • 단일 bar plot (Matplotlib 또는 pandas .plot(kind='bar'))

지시 사항

  1. “고득점자” 필터: 세 과목이 모두 ≥ 80
  2. 부모 학력 수준별 전체 학생 수(분모)와 고득점자 수(분자) 계산
  3. 비율(%) = (분자 / 분모) × 100 → 소수점 1자리 반올림
  4. 내림차순으로 정렬 후 단일 막대그래프 1개로 시각화 (y축 0~100 권장)

시각화 요구

  • 그래프 1개(서브플롯 X)
  • 제목/축 라벨 설정, x라벨 회전(필요 시)
  • 예상 결과


🎯 과정

1. 사용할 csv 파일을 불러온다.
2. 다중 조건 필터링 : 3과목 모두 80점 이상, 시리즈->데이터프레임화
3. 고득점자(3과목 모두 80점 이상인 학생)의 부모 학업수준별 개수
4. 전체 학생의 부모 학업수준별 개수
5. 비율 = ( 고득점자 / 전체 ) * 100
6. 내림차순, 소수 첫째자리
7. plot.bar 로 막대그래프 생성

 

📊 전처리 및 시각화 코드

import pandas as pd
import matplotlib.pyplot as plt

# 파일 불러오기
df = pd.read_csv("StudentsPerformance.csv")

# 다중 조건 필터링 : 3과목 모두 80점 이상, 시리즈 -> 데이터프레임화
high_score = df[(df['math score'] >= 80) & (df['reading score'] >= 80) & (df['writing score'] >= 80)]

# 고득점자 그룹화 : 3과목 모두 80점 이상인 학생의 부모 학업수준별 개수
high_group = high_score.groupby('parental level of education').size()
print(high_group)

# 전체 그룹화 : 전체 학생의 부모 학업수준별 개수
total_group = df.groupby('parental level of education').size()
print(total_group)

# 비율 = (고득점자 그룹/ 전체그룹)*100
rate = (high_group / total_group) *100

# 내림차순, 소숫점 1번째, 🔥🔥🔥 다시 rate을 변수로 할당해야 변수'rate'을 사용할 때, 정렬/소숫점이 적용됨! 🔥🔥🔥
✅ rate = rate.sort_values(ascending=False).round(1)
print(rate)

# plot 바 그래프 생성, 시리즈의 (인덱스, 밸류)
plt.bar(rate.index, rate.values, width=0.5)
plt.xlabel("parental level of education")
plt.ylabel("percentage (%)")
plt.title("High Achiever Rate (>=80 in all) by Parental Education[%]")
plt.tight_layout()
plt.ylim(0, 100)           📌 y축 범위
plt.xticks(rotation=30)    📌 x축 값들 기울기 표현
plt.show()

아래와 같이 막대 그래프가 생성되었다.

 

💡 알게된 점

1️⃣  Series 형태에서 시각화 할 때, 주로 matplotlib 사용
      DataFrame 형태에서 시각화 할 때, 주로 seaborn 사용 ➡️ sns.plot(data=df, x="  ", y="  ")

2️⃣  value_counts()는 시리즈 형태 전용 매서드 : 값의 분포
      size()는 데이터프레임 형태 매서드 : 데이터의 크기? 개수? 

3️⃣  그룹화 할 때 차이점은 예를들어
      df.groupby('컬럼1')['컬럼2'].mean().sort_values(...) 처럼 수치(int, float)값을 가지는 ['컬럼2']를 포함하고,
      df.groupby('컬럼1).size() 처럼 그룹화할 컬럼 하나만을 포함한다.