11-1 데이터 집계
데이터 집계하기 - groupby 메서드
수집한 데이터를 바탕으로 평균이나 합 등을 구하여 의미 있는 값을 도출해 내는 것을 '집계'라고 한다. 데이터를 집계하면 전체 데이터를 요약, 정리하여 볼 수 있기 때문에 분석이 훨씬 편해진다. 그러면 groupby 메서드로 평균값을 구하는 과정을 통해 데이터 집계가 무엇인지 알아보겠다.
import pandas as pd
df = pd.read_csv('doit_pandas_data/data/gapminder.tsv', sep = '\t')
다음은 year 열을 기준으로 데이터를 그룹화한 다음 lifeExp 열의 평균을 구한 것이다.¶
avg_life_exp_by_year = df.groupby('year').lifeExp.mean()
print(avg_life_exp_by_year)
year 1952 49.057620 1957 51.507401 1962 53.609249 1967 55.678290 1972 57.647386 1977 59.570157 1982 61.533197 1987 63.212613 1992 64.160338 1997 65.014676 2002 65.694923 2007 67.007423 Name: lifeExp, dtype: float64
분할-반영-결합 과정 살펴보기 - groupby 메서드
앞에서 groupby 메서드를 사용해 lifeExp 열의 연도별 평균값을 구했다. 그러면 실제로 groupby 메서드는 어떤 과정을 통해 데이터를 집계할까? groupby 메서드 자체를 분해하여 살펴보는 것은 불가능하기 때문에 비슷한 연산을 수행하는 메서드를 순서대로 실행하며 알아보자.
years = df.year.unique()
print(years)
[1952 1957 1962 1967 1972 1977 1982 1987 1992 1997 2002 2007]
그런 다음에는 연도별로 평균값을 구한다. 그러려면 일단 각 연도별로 데이터를 추출해야 한다. 다음은 1952년의 데이터를 추출한 것이다. 이 과정을 '반영' 작업의 한 부분이라고 이해하자.¶
y1952 = df.loc[df.year == 1952, :]
print(y1952.head())
country continent year lifeExp pop gdpPercap 0 Afghanistan Asia 1952 28.801 8425333 779.445314 12 Albania Europe 1952 55.230 1282697 1601.056136 24 Algeria Africa 1952 43.077 9279525 2449.008185 36 Angola Africa 1952 30.015 4232095 3520.610273 48 Argentina Americas 1952 62.485 17876956 5911.315053
아직 lifeExp 열의 평균값을 구하지 않았다. 다음은 위에서 추출한 1952년의 데이터에서 lifeExp 열의 평균값을 구한 것이다. 이 과정도 '반영' 작업의 한 부분이다.¶
y1952_mean = y1952.lifeExp.mean()
print(y1952_mean)
49.05761971830987
위의 두번째 세번째 과정을 반복하여 남은 연도의 평균값을 구하면 비로소 '반영' 작업이 끝난다.¶
y1957 = df.loc[df.year == 1957, :]
y1957_mean = y1957.lifeExp.mean()
print(y1957_mean)
51.507401126760534
y1962 = df.loc[df.year == 1962, :]
y1962_mean = y1962.lifeExp.mean()
print(y1962_mean)
53.60924901408449
y2007 = df.loc[df.year == 2007, :]
y2007_mean = y2007.lifeExp.mean()
print(y2007_mean)
67.00742253521126
마지막으로 연도별로 계산한 lifeExp의 평균값을 합친다. 바로 이 과정이 '결합' 작업이다.¶
df2 = pd.DataFrame({"year":[1952, 1957, 1962, 2007],
"":[y1952_mean, y1957_mean, y1962_mean, y2007_mean]})
print(df2)
year 0 1952 49.057620 1 1957 51.507401 2 1962 53.609249 3 2007 67.007423
groupby 메서드와 함께 사용하는 집계 메서드
다음은 집계 메서드를 정리한 표이다. 이후에 수행할 실습에서 자주 등장하는 메서드이니 미리 읽어보고 넘어가는 것이 좋다.
집계 메서드¶
메서드 | 설명 |
---|---|
count |
누락값을 제외한 데이터 수를 반환 |
size |
누락값을 포함한 데이터 수를 반환 |
mean |
평균값 반환 |
std |
표준편차 반환 |
min |
최솟값 반환 |
quantile(q=0.25) |
백분위수 25% |
quantile(q=0.50) |
백분위수 50% |
quantile(q=0.75) |
백분위수 75% |
max |
최댓값 반환 |
sum |
전체 합 반환 |
var |
분산 반환 |
sem |
평균의 표준편차 반환 |
describe |
데이터 수, 평균, 표준편차, 최소값, 백분위수(25,50,75%), 최대값을 모두 반환 |
first |
첫 번째 행 반환 |
last |
마지막 행 반환 |
nth |
n번째 행 반환 |
agg 메서드로 사용자 함수와 groupby 메서드 조합하기
라이브러리에서 제공하는 집계 메서드로 원하는 값을 계산할 수 없는 경우에는 직접 함수를 만들어서 사용해야 한다. 이번에는 사용자 함수와 groupby 메서드를 조합해서 사용해 보겠다. 사용자 함수와 groupby 메서드를 조합하려면 agg 메서드를 이용해야 한다.
def my_mean(values):
n = len(values)
sum = 0
for value in values:
sum += value
return sum / n
다음은 위에서 만든 함수를 groupby 메서드와 조합하기 위해 agg 메서드를 사용한 것이다. 결과를 보면 mean 메서드를 사용하여 얻은 값과 동일하다는 것을 알 수 있다.¶
agg_my_mean = df.groupby('year').lifeExp.agg(my_mean)
print(agg_my_mean)
year 1952 49.057620 1957 51.507401 1962 53.609249 1967 55.678290 1972 57.647386 1977 59.570157 1982 61.533197 1987 63.212613 1992 64.160338 1997 65.014676 2002 65.694923 2007 67.007423 Name: lifeExp, dtype: float64
def my_mean_diff(values, diff_value):
n = len(values)
sum = 0
for value in values:
sum += value
mean = sum / n
return mean - diff_value
다음은 연도별 평균 수명에서 전체 평균 수명을 뺀 값을 구한 것이다. agg 메서드의 첫 번째 인자에 my_mean_diff 함수를 전달하고 두 번째 인자에 전체 평균 수명값을 전달했다.¶
global_mean = df.lifeExp.mean()
print(global_mean)
59.47443936619714
agg_mean_diff = df.groupby('year').lifeExp.agg(my_mean_diff, diff_value=global_mean)
print(agg_mean_diff)
year 1952 -10.416820 1957 -7.967038 1962 -5.865190 1967 -3.796150 1972 -1.827053 1977 0.095718 1982 2.058758 1987 3.738173 1992 4.685899 1997 5.540237 2002 6.220483 2007 7.532983 Name: lifeExp, dtype: float64
여러 개의 집계 메서드 한 번에 사용하기
여러 개의 집계 메서드를 한 번에 사용하고 싶다면 어떻게 해야 할까? 집계 메서드를 리스트나 딕셔너리에 담아 agg 메서드에 전달하면 된다.
import numpy as np
gdf = df.groupby('year').lifeExp.agg([np.count_nonzero, np.mean, np.std])
print(gdf)
count_nonzero mean std year 1952 142 49.057620 12.225956 1957 142 51.507401 12.231286 1962 142 53.609249 12.097245 1967 142 55.678290 11.718858 1972 142 57.647386 11.381953 1977 142 59.570157 11.227229 1982 142 61.533197 10.770618 1987 142 63.212613 10.556285 1992 142 64.160338 11.227380 1997 142 65.014676 11.559439 2002 142 65.694923 12.279823 2007 142 67.007423 12.073021
이번에는 집계 메서드를 딕셔너리에 담아 agg 메서드에 전달해 보겠다. 딕셔너리의 키로 집계 메서드를 적용할 열 이름을 전달하고 딕셔너리의 값으로 집계 메서드를 전달하면 된다.¶
gdf_dict = df.groupby('year').agg({'lifeExp': 'mean', 'pop': 'median', 'gdpPercap': 'median'})
print(gdf_dict)
lifeExp pop gdpPercap year 1952 49.057620 3943953.0 1968.528344 1957 51.507401 4282942.0 2173.220291 1962 53.609249 4686039.5 2335.439533 1967 55.678290 5170175.5 2678.334740 1972 57.647386 5877996.5 3339.129407 1977 59.570157 6404036.5 3798.609244 1982 61.533197 7007320.0 4216.228428 1987 63.212613 7774861.5 4280.300366 1992 64.160338 8688686.5 4386.085502 1997 65.014676 9735063.5 4781.825478 2002 65.694923 10372918.5 5319.804524 2007 67.007423 10517531.0 6124.371108
출처 : Do it! 데이터 분석을 위한 판다스
'Python > Pandas' 카테고리의 다른 글
<파이썬 판다스> Chapter 11-3 데이터 필터링 (0) | 2023.05.19 |
---|---|
<파이썬 판다스> Chapter 11-2 데이터 변환 (0) | 2023.05.19 |
<파이썬 판다스> Chapter 10-3 apply 메서드 활용하기 - 고급 (0) | 2023.05.14 |
<파이썬 판다스> Chapter 10-2 apply 메서드 활용하기 - 기초 (0) | 2023.05.14 |
<파이썬 판다스> Chapter 10-1 간단한 함수 만들기 (0) | 2023.05.14 |