문제
문제 : https://www.acmicpc.net/problem/2108
통계학에서 N개 수를 대표하는 기본 통계값에는 다음과 같은 것들이 있다.
- 산술평균 : N개의 수의 합을 N으로 나눈 것
- 중앙값 : N개의 수를 오름차순으로 나열했을 때 그 중앙에 위치하는 값
- 최빈값 : N개의 수 중 가장 많이 나타나는 값
- 범위 : N개의 수중 최댓값과 최솟값의 차이
첫째 줄에 수의 개수 N을 입력받고, 다음 N개 줄에 걸쳐 정수를 입력받을 때 네 가지 기본 통계값을 구하여라.
접근
통계 등의 데이터를 처리할 때는 numpy를 곧잘 사용하는데, 이번 글에서는 numpy 사용 없이 풀이해보려고 한다.
먼저 입력 데이터는 다음과 같이 선언했다.
import sys
N = int(sys.stdin.readline())
list_num = [int(sys.stdin.readline()) for _ in range(N)]
산술평균 (avg/mean)
문제에 나온 그대로 구현하면 된다. 단, 소수점 첫째 자리에서 반올림한 값을 출력하므로 round 함수를 사용한다.
round((sum(list_num) / N))
중앙값 (median)
중앙값은 수의 개수가 홀수이면 중간에 있는 값으로 구한다. 만약 수의 개수가 짝수이면 중간에 위치한 앞뒤 숫자의 평균으로 한다.
list_num.sort()
(list_num[N // 2 - 1] + list_num[N // 2]) / 2 if N % 2 == 0 else list_num[N // 2]
최빈값
수 중 가장 많이 등장하는 값이 최빈값이 되므로 Counter를 사용하여 구현했다. 특히 Counter.most_common 함수를 사용하면 빈도수 기준으로 내림차순 정렬된 결과를 얻을 수 있다.
from collections import Counter
counter = Counter(list_num).most_common()
freq_nums = [v for v, c in counter if c == max([cnt[1] for cnt in counter])]
freq_nums[min(1, len(freq_nums) - 1)]
문제에서는 최빈값이 여럿일 때는 최빈값 중 두 번째로 작은 값을 출력한다. 따라서 최빈값이 1개일 때는 freq_nums의 마지막 값을, 2개 이상일 때는 첫 번째 값을 출력한다.
범위
최댓값과 최솟값의 차이이므로 정렬한 값의 마지막 값과 첫번째 값의 차이로 계산한다.
list_num[-1] - list_num[0]
참고 문서
https://www.acmicpc.net/problem/2108