TOP
class="layout-aside-left paging-number">
본문 바로가기
[파이썬 Projects]/<파이썬 - 수학 | 통계학>

[파이썬+통계학] 현대통계학 연습문제 파이썬 구현(ch.2) - 1

by 기록자_Recordian 2024. 10. 4.
728x90
반응형
★ 시작에 앞서

 

해당 내용은 '<현대통계학-제6판>, 다산출판사, 2024' 에 나와있는 챕터별 연습문제를 교재를 응용하여 풀이하고, 수학적인 문제에 대한 답변을 파이썬으로 구현해보기 위해 작성하는 글이다.

해당 답변을 구현하는 방식은 답안지 없이 필자가 스스로 구현하는 것이므로, 정확한 (혹은 가장 효과적인) 답변이 아닐 수 있다. 이 글의 목적은 통계학 공부와 파이썬 프로그래밍 언어 공부를 동시에 하고자 함이며, 통계학을 공부하고 싶으신 분들은 해당 교재를 구매하는 것을 추천한다.

또한, 연습문제 번호 및 문제 내용은 필자가 임의대로 작성하였으며, 교재와는 다를 수 있다.


챕터2 주요 개념: 도수분포표, 상대빈도수, 누적 빈도
챕터2 연습문제 1

 

Q1. A 고등학교 36명의 영어 점수를 입력하고, 다음 물음에 답하는 코드를 구현하라.

1) 75점 이상을 받은 사람의 수

2) 전체 자료 중 75~89점 사이의 점수를 받은 사람의 비율

 

[풀이]

# 영어 점수 입력[리스트 형태]
eng_score = [68, 84, 75, 68, 90, 62, 88, 76, 93, 73, 79, 88, 60, 93, 71, 59,
	85, 75, 61, 65, 75, 74, 62, 95, 78, 68, 72, 66, 78, 82, 94,
            77, 69, 74, 63, 60]

# 75점 이상인 사람 수 계산
count_above_75 = sum(1 for score in eng_score if score >= 75)

# 75~89점 사이인 사람 수 계산
count_between_75_and_89 = sum(1 for score in eng_score if 75 <= score <= 89)

# 비율 계산
total_scores = len(eng_score)
percentage_between_75_and_89 = (count_between_75_and_89 / total_scores) * 100

# 결과 출력
print(f"75점 이상을 받은 사람의 수: {count_above_75}")
print(f"75~89점 사이의 비율: {percentage_between_75_and_89:.2f}%")


챕터2 연습문제2

 

다음은 어느 회사가 채용하고 있는 종업원 65명의 도수분포표다.

임금(X) (단위: 만원) 종업원 수(f)
150~159.999 8
160~169.999 10
170~179.999 16
180~189.999 14
190~199.999 10
200~209.999 5
210~219.999 2

 

1) 첫 번째 등급의 정확한계는? ▶ 하한계: 150 / 상한계: 159.999

2) 세 번째 등급의 중간점은?

3) 각 등급의 구간은?

4) 세 번째 등급의 상대빈도수는?

5) 180만 원 미만을 받는 종업원의 수는 전체의 몇 %인가?

6) 160만 원 이상 200만원 미만을 받는 사람은 전체의 몇 %인가?

 

★ 먼저, 상단에 나온 도수분포표를 작성하는 방법은 pandas를 이용하면 된다.

# 임금 도수분포표
import pandas as pd

# 데이터 생성
data = {
    "임금 구간 (만원)": ["150~159.999", "160~169.999", "170~179.999", "180~189.999", "190~199.999", "200~209.999", "210~219.999"],
    "종업원 수 (f)": [8, 10, 16, 14, 10, 5, 2]
}

# 데이터프레임 생성
df = pd.DataFrame(data)

# 도수분포표 출력
print(df)

 

[풀이]

# 임금 도수분포표
import pandas as pd

# 데이터 생성
data = {
    "임금 구간 (만원)": ["150~159.999", "160~169.999", "170~179.999", "180~189.999", "190~199.999", "200~209.999", "210~219.999"],
    "종업원 수 (f)": [8, 10, 16, 14, 10, 5, 2]
}

# 데이터프레임 생성
df = pd.DataFrame(data)

# 직원 총 수
total_employees = df['종업원 수 (f)'].sum()

# 임금 범위의 최솟값과 최댓값 변환
min_value = 150
max_value = 219.999

# 등급의 수 계산
num_grades = len(df)

# 답안
midpoint_third_grade = (170 + 179.999) / 2
grade_interval = (max_value - min_value) / num_grades
relative_frequency_third_grade = df.iloc[2]['종업원 수 (f)'] / total_employees
employees_below_1_8M = df.iloc[0:3]['종업원 수 (f)'].sum()
percentage_below_1_8M = (employees_below_1_8M / total_employees) * 100
employees_between_1_6M_and_2M = df.iloc[1:5]['종업원 수 (f)'].sum()
percentage_between_1_6M_and_2M = (employees_between_1_6M_and_2M / total_employees) * 100

# 답안 출
print(f"2) 세 번째 등급의 중간점: {midpoint_third_grade}")
print(f"3) 각 등급의 구간: {grade_interval}")
print(f"4) 세 번째 등급의 상대 빈도수: {relative_frequency_third_grade:.2f}")
print(f"5) 전체 직원 중 180만 원 미만을 받는 종업원 수 비율: {percentage_below_1_8M:.2f}%")
print(f"6) 전체 직원 중 160만 원 이상 200만 원 미만을 받는 종업원 수 비율: {percentage_between_1_6M_and_2M:.2f}%")

 

+ 만약, 해당 도수분포표에 각 등급별 상대 빈도수 및 합계가 구해진 표를 생성한다면?

# 도수분포표에 등급별 상대 빈도수와 하단에 합계 만들기
import pandas as pd

# 기존 도수분포표
data = {
    "임금 구간 (만원)": ["150~159.999", "160~169.999", "170~179.999", "180~189.999", "190~199.999", "200~209.999", "210~219.999"],
    "종업원 수 (f)": [8, 10, 16, 14, 10, 5, 2]
}

# 데이터프레임 생성
df = pd.DataFrame(data)

# 총 직원 수 계산
total_employees = df["종업원 수 (f)"].sum()

# 상대 빈도수 구하기
df["상대 빈도수"] = df["종업원 수 (f)"] / total_employees

# 새로운 행 생성
total_row = pd.DataFrame({
    "임금 구간 (만원)": ["합계"],
    "종업원 수 (f)": [total_employees],
    "상대 빈도수": [1.0]  # 총합은 100
})

# 새로운 행 삽입된 표 생성하기
df = pd.concat([df, total_row], ignore_index=True)

# 표 출력하기
print(df)


챕터2 연습문제3

 

다음은 어느 학교 학생들의 혈액형을 조사한 도수분포표다.

혈액형 1반 2반 3반
A 8 16 15
B 8 12 6
O 2 8 6
AB 2 4 3
합계 20 40 30

 

1) 각 학급별 상대적 빈도를 구하라

2) 혈액형이 B형인 학생의 비율이 가장 높은 반은 어디인가?

 

먼저, 상단의 나온 도수분포표를 pandas를 이용하여 표로 작성한다.

# 학생들 혈액형 도수분포표
import pandas as pd

data = {
    "혈액형": ["A", "B", "O", "AB"],
    "1반": [8, 8, 2, 2],
    "2반": [16, 12, 8, 4],
    "3반": [15, 6, 6, 3]
}

# 데이터프레임 생성
df_1 = pd.DataFrame(data)

# 각 학급별 학생 수 합계
total_1 = df_1["1반"].sum()
total_2 = df_1["2반"].sum()
total_3 = df_1["3반"].sum()


# 합계 행 추가
total_row = pd.DataFrame({
    "혈액형": ["합계"],
    "1반": [total_1],
    "2반": [total_2],
    "3반": [total_3],
})

# 새로운 행 삽입된 표 생성하기
df_1 = pd.concat([df_1, total_row], ignore_index=True)

print(df_1)

 

[풀이]

# 학생들 혈액형 도수분포표
import pandas as pd

data = {
    "혈액형": ["A", "B", "O", "AB"],
    "1반": [8, 8, 2, 2],
    "2반": [16, 12, 8, 4],
    "3반": [15, 6, 6, 3]
}

# 데이터프레임 생성
df_1 = pd.DataFrame(data)

# 각 학급별 학생 수 합계
total_1 = df_1["1반"].sum()
total_2 = df_1["2반"].sum()
total_3 = df_1["3반"].sum()


# 합계 행 추가
total_row = pd.DataFrame({
    "혈액형": ["합계"],
    "1반": [total_1],
    "2반": [total_2],
    "3반": [total_3],
    "상대 빈도수_1반": [1.0],
    "상대 빈도수_2반": [1.0],
    "상대 빈도수_3반": [1.0]
})

# 상대 빈도수 구하기
df_1["상대 빈도수_1반"] = df_1["1반"] / total_1
df_1["상대 빈도수_2반"] = df_1["2반"] / total_2
df_1["상대 빈도수_3반"] = df_1["3반"] / total_2



# 새로운 행 삽입된 표 생성하기
df_1 = pd.concat([df_1, total_row], ignore_index=True)

print(df_1)

 

순서를 보기 좋게 바꾼다.

# 학생들 혈액형 도수분포표
import pandas as pd

data = {
    "혈액형": ["A", "B", "O", "AB"],
    "1반": [8, 8, 2, 2],
    "2반": [16, 12, 8, 4],
    "3반": [15, 6, 6, 3]
}

# 데이터프레임 생성
df_1 = pd.DataFrame(data)

# 각 학급별 학생 수 합계
total_1 = df_1["1반"].sum()
total_2 = df_1["2반"].sum()
total_3 = df_1["3반"].sum()


# 합계 행 추가
total_row = pd.DataFrame({
    "혈액형": ["합계"],
    "1반": [total_1],
    "2반": [total_2],
    "3반": [total_3],
    "상대 빈도수_1반": [1.0],
    "상대 빈도수_2반": [1.0],
    "상대 빈도수_3반": [1.0]
})

# 상대 빈도수 구하기
df_1["상대 빈도수_1반"] = df_1["1반"] / total_1
df_1["상대 빈도수_2반"] = df_1["2반"] / total_2
df_1["상대 빈도수_3반"] = df_1["3반"] / total_2

# 칼럼 재정렬
new_order = ["혈액형", "1반", "상대 빈도수_1반", 
             "2반", "상대 빈도수_2반", 
             "3반", "상대 빈도수_3반"]

df = df_1[new_order]

# 새로운 행 삽입된 표 생성하기
df = pd.concat([df, total_row], ignore_index=True)


# 새로운 표 출력
print(df)

 

혈액형이 B형인 학생의 비율이 가장 높은 반은

# 혈액형이 B형인 학생의 비율이 가장 높은 반 구하기
import pandas as pd

data = {
    "혈액형": ["A", "B", "O", "AB"],
    "1반": [8, 8, 2, 2],
    "2반": [16, 12, 8, 4],
    "3반": [15, 6, 6, 3]
}

# 데이터프레임 생성
df_1 = pd.DataFrame(data)

# 각 학급별 학생 수 합계
total_1 = df_1["1반"].sum()
total_2 = df_1["2반"].sum()
total_3 = df_1["3반"].sum()

# 각 학급별 B형 학생의 정확한 수
students_with_b_class_1 = df.loc[df['혈액형'] == 'B', '1반'].values[0]
students_with_b_class_2 = df.loc[df['혈액형'] == 'B', '2반'].values[0]
students_with_b_class_3 = df.loc[df['혈액형'] == 'B', '3반'].values[0]

# 각 학급별 B형 학생 비율 계산
percentage_b_class_1 = (students_with_b_class_1 / total_1) * 100
percentage_b_class_2 = (students_with_b_class_2 / total_2) * 100
percentage_b_class_3 = (students_with_b_class_3 / total_3) * 100

# 비율 딕셔너리 생성
percentage_dict = {
    "1반": percentage_b_class_1,
    "2반": percentage_b_class_2,
    "3반": percentage_b_class_3
}

# 가장 높은 비율을 가진 반 찾기
highest_class = max(percentage_dict, key=percentage_dict.get)
highest_percentage = percentage_dict[highest_class]

# 결과 표시
print("1반의 B형 학생 비율:", percentage_b_class_1)
print("2반의 B형 학생 비율:", percentage_b_class_2)
print("3반의 B형 학생 비율:", percentage_b_class_3)
print(f"B형 학생의 비율이 가장 높은 반: {highest_class}, 비율: {highest_percentage:.2f}%.")

 


다음 내용

 

[파이썬+통계학] 현대통계학 연습문제 파이썬 구현(ch.2) - 2

★ 시작에 앞서 ★ 해당 내용은 ', 다산출판사, 2024' 에 나와있는 챕터별 연습문제를 교재를 응용하여 풀이하고, 수학적인 문제에 대한 답변을 파이썬으로 구현해보기 위해 작성하는 글이다.해

puppy-foot-it.tistory.com

 

728x90
반응형