혼자 공부하는 데이터 분석 with 파이썬 04-1 통계로 요약하기

손지호·2024년 1월 28일
0
post-custom-banner

기술통계(descrptive statistics) : 테크니컬(technical)한 어떤 것을 지칭하는 것이 아니라 자료의 내용을 압축하여 설명하는 방법. 다른 말로는 요약 통계(summary statistics) 라 부른다. 정량적인 수치로 전체 데이터의 특징을 요약하거나 이해하기 쉬운 간단한 그래프를 사용한다. 대표적인 통계량에는 평균, 표준편차 등이 있음. 데이터 시각화를 아우르는 이러한 데이터 분석 방법을 탐색적 데이터 분석(exploratory data analysis)라고 한다.

기술통계 구하기

# ns_book6.csv 파일 다운로드
import gdown

gdown.download('https://bit.ly/3736JW1', 'ns_book6.csv', quiet=False)

# 데이터프레임으로 불러 온 후, 다섯 개 행 출력
import pandas as pd

ns_book6 = pd.read_csv('ns_book6.csv', low_memory=False)
ns_book6.head()
>>> 번호	도서명	저자	출판사	발행년도	ISBN	세트 ISBN	부가기호	권	주제분류번호	도서권수	대출건수	등록일자
0	1	인공지능과 흙	김동훈 지음	민음사	2021.0	9788937444319	NaN	NaN	NaN	NaN	1	0	2021-03-19
1	2	가짜 행복 권하는 사회	김태형 지음	갈매나무	2021.0	9791190123969	NaN	NaN	NaN	NaN	1	0	2021-03-19
2	3	나도 한 문장 잘 쓰면 바랄 게 없겠네	김선영 지음	블랙피쉬	2021.0	9788968332982	NaN	NaN	NaN	NaN	1	0	2021-03-19
3	4	예루살렘 해변	이도 게펜 지음, 임재희 옮김	문학세계사	2021.0	9788970759906	NaN	NaN	NaN	NaN	1	0	2021-03-19
4	5	김성곤의 중국한시기행 : 장강·황하 편	김성곤 지음	김영사	2021.0	9788934990833	NaN	NaN	NaN	NaN	1	0	2021-03-19

describe() 메서드 : 기본적인 몇 가지 기술통계 자동으로 추출

ns_book6.describe()
>>> 번호	발행년도	도서권수	대출건수
count	379976.000000	379976.000000	379976.000000	379976.000000
mean	201726.332847	2008.516306	1.135874	11.504629
std	115836.454596	8.780529	0.483343	19.241926
min	1.000000	1947.000000	0.000000	0.000000
25%	102202.750000	2003.000000	1.000000	2.000000
50%	203179.500000	2009.000000	1.000000	6.000000
75%	301630.250000	2015.000000	1.000000	14.000000
max	401681.000000	2650.000000	40.000000	1765.000000
  • count : 누락된 값을 제외한 데이터 개수를 나타낸다.
  • mean : 평균을 구한다.
  • std : 표준편차를 구한다.
  • min : 최솟값을 구한다.
  • 50% : 중앙값을 구한다.
  • 25% & 75% : 순서대로 늘어 놓았을 때 25% 지점과 75% 지점에 놓인 값.
  • max : 최댓값을 구한다.

위 결과에서 이상한 점은 도서권수 최솟값이 0인 것이다. 도서를 한 권도 가지고 있지 않은데 대출 데이터에 포함되어 있다. 이유는 알 수 없지만 이런 도서가 많다면 이를 걸러내야 할지 고민해야 한다!

3장에서 했던 것처럼 불리언 배열sum() 함수를 활용하여 도서권수가 0인 도서의 행 개수를 쉽게 카운트 할 수 있다.

sum(ns_book6['도서권수']==0) → '도서권수' 열의 값이 0인 행 개수를 샌다.
>>> 3206

3천 개가 넘는 도서권수가 0이다. 전체 데이터(379,976개)에 비하면 1%가 채 안 되기에 무시할 만한 수치이다.
하지만 이런 도서가 꽤 많다면 어떤 이유에서 0권인지 이를 데이터 분석에서 제외할지 판단해야 한다. 처리 기준은 해결할 문제에 따라 다르며 이러한 결정이 분석 결과에 믄 영향을 미칠 수 있다. 여기서는 실제로 없는 도서 대출 데이터는 의미가 없다고 생각하여 제외.

ns_book7 = ns_book6[ns_book6['도서권수']>0]

describe() 메서드는 기본적으로 데이터의 25%, 50%, 75%에 위치한 값 보여준다. 원하는 위치의 값을 보고 싶다면 percentiles 매개변수에 위치를 지정하면 된다.

# 30%, 60%, 90%에 위치한 값
ns_book7.describe(percentiles=[0.3, 0.6, 0.9])
>>> 번호	발행년도	도서권수	대출건수
count	376770.000000	376770.000000	376770.000000	376770.000000
mean	202977.476649	2008.460076	1.145540	11.593439
std	115298.245784	8.773148	0.473853	19.279409
min	1.000000	1947.000000	1.000000	0.000000
30%	124649.700000	2004.000000	1.000000	2.000000
50%	204550.500000	2009.000000	1.000000	6.000000
60%	243537.400000	2011.000000	1.000000	8.000000
90%	361341.100000	2018.000000	2.000000	28.000000
max	401681.000000	2650.000000	40.000000	1765.000000

중앙값 50% 포함하여 30%, 60%, 90%에 해당되는 값 출력됨.
또한 도서권수가 0인 도서의 대출 데이터도 제외되어 처음 기술통계를 출력했을 떄와 조금씩 수치가 차이나는 것도 있다.

열의 데이터 타입이 수치가 아닌 데이터 타입의 열의 기술통계를 보고 싶다면 include 매개변수에 데이터 타입을 지정할 수 있다.

# 예를 들어 object 타입의 열에 대한 통계를 내보자.
ns_book7.describe(include='object')
>>> 도서명	저자	출판사	ISBN	세트 ISBN	부가기호	권	주제분류번호	등록일자
count	376770	376770	376770	376770	55866	308252	61793	359792	376770
unique	336408	248850	21875	350810	14875	17	834	12467	4562
top	승정원일기	세종대왕기념사업회 [편]	문학동네	9788937430299	9788937460005	0	1	813.6	1970-01-01
freq	250	303	4410	206	702	158235	13282	14816	28185

count 행은 누락된 값을 제외한 데이터 개수를 나타내고, unique 행은 고유한 값의 개수를 나타낸다. top 행은 가장 많이 등장하는 값을 나타낸다. freq 행은 top 행에 등장하는 항목의 빈도수. 실행 결과에 따르면 '도서명' 열에서 가장 많이 등장하는 데이터는 '승정원일기'로 250회나 나온다!
판다스의 describe() 메서드는 이처럼 다양한 통계량을 간편하게 요약해서 확인할 수 있다.


평균 구하기

평균은 비교적 쉽게 이해할 수 있는 통계량이다. 숫자 값을 모두 더해 개수로 나눈 것.
평균 = (a + b + c) / 3
그치만 숫자가 10개나 남산도서관 대출 데이터처럼 많아지면 길고 지루하게 쓰이게 되기에 수학 기호를 사용한다.

이런 덧셈을 파이썬으로 구현 가능하다!

x = [10, 20, 30]
sum = 0
for i in range(3):
    sum += x[i]
print("평균:", sum / len(x))
평균: 20.0

파이썬의 range() 함수는 하나의 숫자를 입력할 경우 0부터 입력된 숫자 직전까지 반복할 수 있는 객체를 만들어 준다. 따라서 for 문에 range(3)를 사용하면 변수 i에 0, 1, 2를 대입할 수 있다. 결국 x[ 0 ]에서 x[ 2 ]까지 반복하며 sum에 값을 누적한다.
[227 그림삽입]
이와 동일한 반복 구조를 합 기호(∑)를 사용해 표현할 수 있다.
[228 그림삽입]
∑ 기호 아래에는 사용할 인덱스와 시작 값을 지정한다. 여기에서는 인덱스에 영문자 i를 사용하고 1부터 시작한다. 그리고 ∑ 기호 위에는 종료 값을 지정한다. i의 종료 값은 3으로 지정. i는 1에서부터 3까지 바뀌며 xi에 대입되어 x1 + x2 + x3 덧셈을 만든다. for 반복문과 비교해 생각하면 쉽게 이해 가능!

mean() 메서드

판다스 데이터프레임과 시리즈 객체는 평균을 계산하는 mean() 메서드를 제공한다.

ns_book7['대출건수'].mean()
>>> 11.593438968070707

중앙값 구하기

중앙값(median)은 말 그대로 전체 데이터를 순서대로 늘어 놓았을 때 중앙에 위치한 값. 앞서 descride() 메서드의 기본 출력에서 50% 위치의 값이 중앙값에 해당됨.

median() 메서드

ns_book7['대출건수'].median()
>>> 6.0

데이터 개수가 홀수일 때는 중앙값을 결정하기 쉽다. 짝수일때는 어떻게 해야할까??
짝수일 경우 가운데 두 개의 값을 평균하여 중앙값을 결정한다.

temp_df = pd.DataFrame([1,2,3,4])
temp_df.median()
>>> 0    2.5
dtype: float64

중복값 제거하고 중앙값 구하기

drop_duplicates() 메서드 사용해 '대출건수' 열에서 중복된 값을 가진 행을 제거 후 중앙값 구하자.

ns_book7['대출건수'].drop_duplicates().median()
>>> 183.0

[230 그림 사빕]


최솟값, 최댓값 구하기

중앙값과 함께 자주 사용되는 통계량은 최솟값, 최댓값이다. 판다스에서는 각각 min() 메서드max() 메서드를 제공한다.

ns_book7['대출건수'].min()
>>> 0

ns_book7['대출건수'].max()
>>> 1765

분위수 구하기

분위수(quantile) : 데이터를 순서대로 늘어 놓았을 때 이를 균등하게 간격으로 나누는 기준. 예를 들어 이분위수는 전체 데이터를 두 구간으로 나누기 때문에 중앙값에 해당함.
[231 그림삽입]
가장 많이 사용하는 분위수는 사분위수(quartile). 사분위수는 순서대로 정렬된 데이터를 네 구간으로 나눈다. 따라서 사분위수는 3개가 나오고 각각 25%, 50%, 75%에 해당하고 제 1사분위수, 중앙값 제 2사분위수, 제 3분위수라고 부른다.
[232 그림삽입]


quantile() 메서드

판다스에서 분위수 값을 계산할 때는 quantile() 메서드를 사용한다.

ns_book7['대출건수'].quantile(0.25)
>>> 2.0

# 25%, 50%, 75% 위치한 값 추출
ns_book7['대출건수'].quantile([0.25,0.5,0.75])
>>> 0.25     2.0
	0.50     6.0
	0.75    14.0
	Name: 대출건수, dtype: float64
# 1, 2, 3, 4, 5 다섯 개 있을 때 90% 위치는??
pd.Series([1,2,3,4,5]).quantile(0.9)
>>> 4.6

quantile() 메서드는 interpolation 매개변수에서 중간 값을 계산하는 방법을 결정한다. 위 코드는 interpolation 매개변수를 따로 지정하지 않아서 기본값으로 계산되었다. 예를 들어 4와 5 사이에서 90%에 해당하는 분위수를 찾을 때, 다음 그림처럼 4의 분위수 0.75와 5의 분위수 1.0을 사용해 간단한 비례식을 세울 수 있다.
[233 그림삽입]
interpolation 매개변수의 또 다른 보간 방식
interpolation 매개변수는 'linear' 외에도 여러 가지 다른 보간 방식을 제공한다. 'midpoint'는 분위수에 상관없이 무조건 두 수 사이의 중앙값을 사용한다.

pd.Series([1,2,3,4,5]).quantile(0.9, interpolation='midpoint')
>>> 4.5

'nearest'는 두 수 중에서 가까운 값 선택. 이 경우는 0.9가 1.0에 더 가깝기 때문에 5가 된다.

pd.Series([1,2,3,4,5]).quantile(0.9, interpolation='nearest')
>>> 5

이 외에도 두 수 중 작은 값을 선택하는 'lower', 큰 값을 선택하는 'higher'가 있다.


백분위 구하기

남산도서관 대출 데이터에서 대출건수 10이 위치한 백분위를 어떻게 찾을까?!
판다스에서 이에 대한 메서드를 제공하진 않지만, 간단한 트릭으로 유사한 결과를 얻을 수 있다. 먼저 '대출건수' 열의 값이 10보다 작은지 비교하여 불리언 배열을 만든다.

borrow_10_flag = ns_book7['대출건수'] < 10

[234 그림 삽입]
이렇게 변환한 borrow_10_flag 배열(실제로는 시리즈 객체)에서 True인 개수를 모두 헤아린 후 전체 데이터 개수로 나누면 10보다 작은 대출 건수의 비율을 얻을 수 있다. 데이터의 양이 많다며 ㄴ전체 데이터를 순서대로 놓았을 때 10이 위치한 백분위와 거의 비슷하게 된다.
판다스에서 불리언 자료를 산술 연산하면 True는 1, False는 0으로 취급한다. 따라서 다음처럼 borrow_10_flag 배열에서 mean() 메서드를 호출하여 평균을 구하면 10보다 작은 값이 차지하는 비율을 간단히 얻을 수 있다.

borrow_10_flag.mean()
>>> 0.6402712530190833

# 10에 대한 백분위는 0.65 정도.
# quantile() 메서드에 백분위 넣어 직접 확인
ns_book7['대출건수'].quantile(0.65)
>>> 10.0

분산 구하기

분산(variance) : 평균으로부터 데이터가 얼마나 퍼져있는지를 나타내는 통계량. 데이터가 가운데 모여 있다면 분산이 작고 넓게 퍼져 있다면 분산이 크다.
[235 그림삽입]
분산은 데이터의 각 값에서 평균을 뺸 다음 제곱한 후 평균처럼 샘플 개수로 나누어 구할 수 있다.
[236 그림삽입]
데이터의 각 값에서 평균 빼면 데이터가 서로 얼마나 멀리 떨어져 있는지 알 수 있음. 또 제곱하면 음수가 뙤는 것을 막아서 평균을 중심으로 좌우의 값이 서로 상쇄되지 않도록 만들어준다. 분산을 앞에서 배운 합 기호로 표시하면 다음과 같다.
[235 그림삽입]

var() 메서드

ns_book7['대출건수'].var()
>>> 371.69563042906674

분산은 데이터가 평균에서 얼마나 퍼져 있는지 나타내는 값이기 때문에 이 결과만 보고 값이 작은지 큰지 판단하기 어렵다.
분산은 제곱을 했기 때문에 데이터가 평균에서 멀어질수록 값이 급격히 커진다. 또 단위가 대출건수의 제곱이 되어 해석하기 조금 어렵다. 이를 보완하기 위해 분산에 제곱근을 취한 표준편차를 사용한다.


표준편차 구하기

표준편차(standard deviation) : 분산에 제곱근을 한 것, 수식 기호는 s를 사용. 반대로 말하면 분산은 표준편차를 제곱한 것이므로 분산을 s^2로 표시했던 것.
분산을 계산했다면 표준편차는 제곱근만 씌우면 되기 때문에 간단.
[237 그림삽입]
따라서 표준편차의 공식도 아래처럼 분산 공식에서 제곱근만 추가됨.
[237 그림삽입]


std() 메서드

ns_book7['대출건수'].std()
>>> 19.279409493785508

→ 229쪽에서 도서 대출건수는 평균 11회가 조금 넘는 것을 알 수 있다. 어떤 도서의 대출 건수를 확인했을 때 평균보다 19만큼 더 많거나 적을 수 있다는 의미! 표준편차는 "평균을 중심으로 데이터가 대략 얼만큼 떨어져 분포해 있는지" 표현하는 값이기 때문!
그런데 평균이 11정도 인데 표준편차는 19! 게다가 대출건수는 음수가 될 수 없는데 이상하다. 아마도 평균보다 훨씬 큰 대출건수가 있기 때문에 표준편차가 큰 것으로 예상할 수 있다.
+ 수식을 코드로 구현해 보세요.
판다스의 std() 메서드를 수식으로 구현하려면 샘플 개수를 n이 아니라 n-1로 나누어야 한다. 이를 자유도(degree of freedom)라고 한다. 제곱근은 넘파이의 sqrt() 함수를 사용하여 구할 수 있다.

import numpy as np
diff = ns_book7['대출건수'] - ns_book7['대출건수'].mean() → 각 '대출건수' 열의 값에서 평균을 뺀다.
np.sqrt( np.sum(diff**2) / (len(ns_book7)-1) ) → 분산의 제곱근 구한다.
19.279409493785508

최빈값 구하기

최빈값(mode) : 데이터에서 가장 많이 등장하는 값.

mode() 메서드

mode() 메서드는 최빈값을 계산함.

ns_book7['도서명'].mode()
 >>> 0    승정원일기
Name: 도서명, dtype: object

# 텍스트뿐만 아니라 수치형에도 적용 가능.
ns_book7['발행년도'].mode()
>>> 0    2012.0
Name: 발행년도, dtype: float64

데이터프레임에서 기술통계 구하기

지금까지 배운 메서드들은 데이터프레임에도 사용할 수 있다. 수치형 열만 연산할 수 있기 때문에 해당 열에만 적용되도록 numeric_only 매개변수를 True로 지정해야 한다.
예를 들어 ns_book7 데이터프레임에서 mean() 메서드를 호출하면 수치형인 네 개의 열에 대한 평균값이 계산된다. 만약 numeric_only 매개변수를 지정하지 않으면 모든 데이터 타입의 열에 대해 수행하기 때문에 시간이 매우 오래 걸리며 경고가 발생한다.

ns_book7.mean(numeric_only=True)
>>> 번호      202977.476649
발행년도      2008.460076
도서권수         1.145540
대출건수        11.593439
dtype: float64

이처럼 mode() 메서드도 데이터프레임에서 호출할 수 있다. ns_book7의 '번호' 열은 모두 고유한 값으로 이루어져 있기 때문에 최빈값을 찾는 것이 의미 없다. 따라서 loc 메서드로 '도서명' 열부터 마지막 열까지에 대해 최빈값을 찾으면 된다.

ns_book7.loc[:, '도서명':].mode()
>>> 도서명	저자	출판사	발행년도	ISBN	세트 ISBN	부가기호	권	주제분류번호	도서권수	대출건수	등록일자
0	승정원일기	세종대왕기념사업회 [편]	문학동네	2012.0	9788937430299	9788937460005	0	1	813.6	1	0	1970-01-01

'도서명' 열에서 가장 많이 등장하는 값은 '승정원일기'이고 '출판사' 열에서 가장 많이 등장하는 값은 '문학동네'. 이떄 결괏값만 보고 승정원일기가 문학동네 출판사의 도서라고 오해하면 안된다. mode() 메서드 출력 결과물 사이에는 서로 연관이 없다는 것을 주의!!

# ns_boo7 데이터프레임을 CSV 파일로 저장한다.
ns_book7.to_csv('ns_book7.csv', index=False)

좀 더 알아보기 _ 넘파이의 기술통계 함수

데이터 분석에서는 판다스를 가장 많이 활용하지만, 넘파이도 여러 가지 기술통계 함수를 제공한다.

평균 구하기

넘파이에서 평균을 구할 때는 mean() 함수average() 함수를 사용한다.

import numpy as np
np.mean(ns_book7['대출건수'])
>>> 11.593438968070707

앞서 판다스 mean() 메서드로 출력한 것과 동일한 값이 출력된다!
average() 함수는 기본적으로 mean() 함수와 동일하게 평균을 계산하는데, weights 매개변수에 가중치 제공하면 가중 평균을 계산한다.
가중 평균은 평균을 구할 때 각 값의 중요도에 따라 가중치를 부여하여 계산하는 평균값이다. 예를 들어 국어와 수학 점수의 평균을 계산하는데 국어 점수가 두 배나 더 중요하다고 가정하자. 이런 경우 국어 줌수에 2를 곱해서 크기를 늘려 줄 수 있다. 이는 마치 국어 점수가 2개인 것과 같다. 따라서 분모를 3으로 나눈다.
(국어 점수 x 2 + 수학 점수) / 3
이것을 수식으로 나타내면,

  • 가중 평균 = (xi wi + x2 w2) / w1 + w2 = ∑2~i=1 (xi * wi) / ∑2~i=1 wi
    두 개의 숫자 x1, x2에 각각의 가중치 w1, w2를 곱하고 전체 가중치 w1 + w2로 나누었다. 그리고 앞에서 보았던 ∑ 기호로 표현한 것이 오른쪽 식이다.

이제 넘파이 average() 함수를 사용해 가중 평균을 계산해보자.

np.average(ns_book7['대출건수'], weights=1/ns_book7['도서권수'])
>>> 10.543612175385386

mean() 함수보다 평균이 조금 낮아짐!
평균에 대해서 조금 더 깊이 생각해보자. 여러 권을 보유한 도서와 그렇지 않은 도서를 공정하게 다루기 위해 대출건수를 도서권수로 나눌 수 있다. 이렇게 하면 모든 도서의 권수가 1일 때 대출건수를 얻게 된다.
예를 들어 10권을 가진 도서의 대출건수가 20회이고 2권을 가진 도서의 대출건수가 10이라고 가정하자. 도서권수를 1로 통일한 대출건수는 각각 20/10 = 2와 10/2 = 5이다. 두 결과를 평균하면 (2+5)/2 = 3.5가 된다.
이런 계산을 남산도서관 대출 데이터에 적용하는 것은 아주 쉽다.

np.mean(ns_book7['대출건수']/ns_book7['도서권수'])
>>> 9.873029861445774

이렇게 평균을 계산한 값도 단순한 평균보다 낮다. 모든 도서권수가 1이기 때문에 도서권수에 따라 대출건수에 미치는 영향을 덜 받았기 때문이다.

# 전체 대출건수를 모두 더한 다음 전체 도서권수로 나눌 수 있다.
# 이렇게 하면 도서에 상관없이 한 권 당 대출건수를 구할 수 있다.
ns_book7['대출건수'].sum()/ns_book7['도서권수'].sum()
>>> 10.120503701300958

중앙값 구하기

median() 함수 사용.

np.median(ns_book7['대출건수'])
>>> 6.0

역시 동일한 값 출력!


최솟값, 최댓값 구하기

min(), max() 함수 사용.

# 최솟값
np.min(ns_book7['대출건수'])
>>> 0

# 최댓값
np.max(ns_book7['대출건수'])
>>> 1765

분위수 구하기

quantile() 함수 사용.

np.quantile(ns_book7['대출건수'], [0.25,0.5,0.75])
>>> array([ 2.,  6., 14.])

넘파이는 percentile() 함수도 제공함. 마찬가지로 분위수 구할 수 있다.


분산 구하기

var() 함수 제공.

np.var(ns_book7['대출건수'])
>>> 371.6946438971496

판다스의 var() 메서드로 계산했을 때와 값이 조금 다름!! (소수저 셋째 자리부터 조금씩 차이남.)

  • n-1 자유도
    여기서는 앞서 계산한 분산 식에서 분모가 n이 아닌 n-1이다!!
    전체 데이터 중에서 수집한 일부 데이터를 표본집단(sample) 또는 표본이라고 부른다. 전체 데이터는 모집단(population) 이라고 부른다.
    모집단은 아예 구할 수 없거나 구하기 매우 어려운 경우가 많다. 그래서 표본집단을 사용해 모집단의 특징을 추정하는 일이 많다. 표본집단은 평균과 n-1개의 샘플 데이터를 알고 있다면 마지막 한 개의 샘플 값은 자동으로 알 수 있다. 이러한 경우를 '자유도(degree of freedom)가 n-1'이라고 한다. 따라서 분산을 계산할 때 분모를 n이 아니라 n-1로 나눈다.

반면에 넘파이의 var() 함수는 n으로 나누기 때문에 판다스와 결과가 다르다. 표본집단으로 모집단의 특징을 추정하려는 것이 아니고, 단순히 일련의 데이터에 대한 분산을 계산하고 싶다면 이렇게 n으로 나누면 된다.
판다스와 넘파이 모두 ddof 매개변수를 사용하여 자유도 차감값을 지정할 수 있다. 판다스 var() 메서드의 ddof 기본값은 1이므로 n-1로 나눗셈하고, 넘파이 var() 함수의 ddof 기본값은 0이므로 n으로 나눗셈한다고 기억하자. 넘파이는 주로 머신러닝 작업에 많이 사용되고 판다스는 데이터 분석에 많이 사용되기에 기본값에 차이가 있다.

# 판다스
ns_book7['대출건수'].var(ddof=0)
>>> 371.6946438971496

# 넘파이
np.var(ns_book7['대출건수'], ddof=1)
>>> 371.69563042906674

앞에서 계산했던 판다스와 넘파이의 분산 결괏값과 정확히 반대이다. 하지만 데이터 개수가 충분하다면 판다스와 넘파이 계산 결과에 차이가 크지 않기 때문에 분산 나타낼 떄 자유도 고려할 필요 없다.


표준편차 구하기

std() 함수 사용. 표준편차도 분산과 마찬가지로 판다스와 넘파이의 자유도 차감값이 다르다. 여기에서는 dof 매개변수를 생략하여 기본값 0으로 계산!

np.std(ns_book7['대출건수'])
>>> 19.27938390865096

최빈값 구하기

넘파이는 직접적으로 최빈값 구하는 함수를 제공하지는 않는다. 하지만 unique() 함수를 사용해 최빈값을 찾을 수 있다. unique() 함수는 배열에서 고유한 값을 찾아준다. return_counts 매개변수를 기본값 False에서 True로 바꿔주면 고유한 값의 등장 횟수도 반환한다. 이를 이용해 가장 많이 등장한 값을 찾아 출력할 수 있다.

# 먼저 unique() 함수를 호출해 고유한 값(values)과 등장 횟수(counts) 배열을 얻는다.
values, counts = np.unique(ns_book7['도서명'], return_counts=True)

# 이후 counts 배열에서 가장 큰 값의 인덱스를 찾는다. argmax() 함수 사용!
max_idx = np.argmax(counts)

# 가장 많은 값의 인덱스 찾았으니 values 배열에서 해당 인덱스의 값을 출력.
values[max_idx]
>>> '승정원일기'

정리

  • 평균은 데이터값을 모두 더한 후 데이터 개수로 나눈 값. 평균은 일상생활에서도 널리 사용되기 때문에 이해하기 쉽지만, 어떤 기준으로 평균을 계산하는지에 따라 조금씩 다른 의미를 가질 수 있다.
  • 중앙값은 전체 데이터를 크기 순서대로 일렬로 늘어 놓았을 때 중간에 위치한 값. 전체 데이터 개수가 짝수일 때는 중간의 두 데이터의 평균을 계산한다.
  • 분위수는 순서대로 나열된 데이터를 일정한 간격으로 나누는 기준점이다. 예를 들어 사분위수는 데이터를 4등분하여 25%, 50%, 75%에 위치한 값이다. 백분위수는 데이터를 100개의 구간으로 나눈다.
  • 분산은 데이터가 평균에서 얼마나 멀리 퍼져 있는지 알려준다. 각 데이터를 평균에서 뺀 다음 제곱한 후 전체 데이터 개수로 나누어 구한다.
  • 표준편차는 분산의 제곱근으로 분산과 마찬가지로 데이터의 분포 정도를 알려준다. 표준편차는 원본 데이터와 단위가 같기 때문에 분산보다 해석하기 쉽다.
  • 최빈값은 데이터에서 가장 많이 등장하는 값을 알려준다. 최빈값은 숫자와 문자 데이터에 모두 적용할 수 있다.

핵심 함수와 메서드

  • DataFrame.describe() : 데이터프레임의 기술통계량을 출력한다.
  • Series.mean() : 데이터에서 평균을 계산한다.
  • numpy.mean() : 입력된 배열의 평균을 계산한다.
  • Series.median() : 데이터에서 중앙값울 찾는다.
  • numpy.median() : 입력된 ㅐㅂ열의 중앙값을 찾는다.
  • Series,quantile() : 데이터에서 분위수를 계산한다.
  • numpy.quantile() : 입력된 배열의 분위수를 계산한다.
  • Series.var() : 데이터의 분산을 계산한다.
  • numpy.var() : 입력된 배열의 분산을 계산한다.
  • Series.std() : 데이터의 표준편차를 계산한다.
  • numpy.std() : 입력된 배열의 표준편차를 계산한다.
  • Series.mode() : 데이터에서 최빈값을 찾는다.
profile
초보 중의 초보. 열심히 하고자 하는 햄스터!
post-custom-banner

0개의 댓글