본문 바로가기
Algorithm/백준 문제풀이

[python] 2108번 - 통계학

by B_Tori 2021. 9. 8.

문제

 

파이썬 풀이

보통 통계값을 파이썬으로 구할 때에는 numpy 라이브러리를 사용했었다.

그러나 알고리즘 풀이에서 numpy 라이브러리를 사용할 수 없다고 해 사용하지 않고 통계값을 구해보았다.

import sys
input = sys.stdin.readline
from collections import Counter

n= int(input().rstrip())
l = [int(input().rstrip()) for _ in range(n)]

avg = round(sum(l)/n) 
l.sort()
middle = l[n//2]
rang = l[-1] - l[0]
c = Counter(l)
result = c.most_common(2)

if len(result) == 2 and result[0][1] == result[1][1] :
  mode = result[1][0]
else :
  mode = result[0][0]

print(avg)
print(middle)
print(mode)
print(rang)

평균값 구하기

리스트의 합을 n값으로 나누어 구했다. 여기서 출력할 때 소수점 첫째자리에서 반올림하여 값이 정수 값으로 출력되도록 해야 한다.

round 함수

소수점을 n번째 까지만 표현하고 반올림하고 싶을 때 사용한다.

사용법은 round(실수, n)으로 n+1번째에서 반올림하여 n번째까지 표현한다.

n을 생략하면 소수점 첫째 자리에서 반올림하여 정수만 나타난다.

n대신 0을 넣으면 소수점 첫째자리에서 반올림을 하지만 결괏값이 2.0처럼 실수로 나타났다.

따라서 n을 생략하는 방법으로 round함수를 사용했더니 정수 값으로 나타나 출력 양식에 맞추기 위해 n을 생략하는 방식을 택했다.

 

중앙값 구하기

중앙값을 구하기 위해 정렬을 사용했다.

리스트를 오름 차순으로 정렬한 뒤 인덱스가 n//2 (정수 나누기)인 값이 중앙값이다.

n이 짝수일 경우 중앙 두 개의 평균을 구해야 하나, 홀수라고 조건을 주었기 때문에 간단하게 //2로 해결할 수 있었다.

 

범위 구하기

이미 정렬한 리스트에서 가장 마지막 요소는 가장 큰 값이고, 첫 번째 요소는 가장 작은 요소이므로

**l[-1] - l[0]**을 통해 구할 수 있었다.

 

최빈값 구하기

최빈값을 구하는 방법이 가장 고민이 되었는데, collections모듈의 Counter클래스를 사용하는 방법을 택하였다. 데이터의 개수를 셀 때 유용한 클래스이다.

Counter클래스

Counter객체에 리스트를 넣어 초기화하면 리스트 안에 있는 원소의 종류에 따라 등장 횟수를 세어 반환해준다.

여러 가지 메서드를 가지고 있는데 이 중 most_common이라는 메서드를 통해 데이터의 개수가 많은 순으로 정렬된 배열을 리턴할 수 있다.

most_common의 인자로 숫자 n을 전달하여 가장 많이 등장하는 상위 n개의 결괏값을 얻을 수 있다.

결괏값은 (문자열, 데이터수)인 튜플 형태로 반환된다.

최빈값이 여러 개인 경우

최빈값이 여러 개인 경우 두 번째로 작은 수를 출력하라고 조건을 걸어두었다.

우선적으로 오름차순으로 정렬되었기 때문에 정렬 기준이 데이터 수로 1차 정렬되고 데이터의 수가 같은 수의 경우 오름차순으로 정렬된다.

최빈값이 여러 개인 경우는 최상위 2개 이상의 값이 같은 값을 가지고 있다는 의미이며, 두 번째로 작은 수를 출력하면 되기 때문에 2개의 최상위 값만 있으면 판단할 수 있었다.

따라서 most_common의 인자로 2를 넘겨주고 두 개의 결과 값이 같은지 비교하고, 다르다면 최빈값은 1개이므로 1번째 값을 출력한다.

또한 애초에 한 가지 문자만 가지고 있어 2개 이상의 결과가 나올 수 없는 경우가 있다. 그렇게 되면 most_common(2)를 해도 결괏값은 1개만 나오게 된다.

따라서 결괏값이 2개 이상이고, 2개의 결괏값의 데이터 빈도 수가 같은 경우에만 두 번째 값을 출력시킨다.

댓글