pandas pivot table

Page content

강의 홍보

공지

제 수업을 듣는 사람들이 계속적으로 실습할 수 있도록 강의 파일을 만들었습니다. 늘 도움이 되기를 바라며. 참고했던 교재 및 Reference는 꼭 확인하셔서 교재 구매 또는 관련 Reference를 확인하시기를 바랍니다.

  • 데이터는 코로나 데이터를 활용했다.

I. Overview

일부의 사람들이 RPython을 사용하지만, 대부분의 사람들은 엑셀을 사용한다. 피벗테이블은 모든 직장인이 알아야 하는 필수 용어로, 전체 데이터를 빠르게 요약해주는 일종의 skill이다.

II. 피벗 테이블 만들기 예제

  • 이제 본격적으로 피벗 테이블을 만들어보자.

(1) 데이터 가져오기

데이터는 코로나 데이터를 활용한다.1 데이터는 아래와 같은 변수로 구성이 되어 있다.

  • dateRep, day, month, year: 기록된 날짜를 의미한다.
  • cases: 한국에서는 확진자수로 정의되었다.
  • deaths: 사망자수이다.
  • countriesAndTerritories, geoId, countryterritoryCode: 국가명과 연관이 있다.
import pandas as pd
from tabulate import tabulate
url = 'https://raw.githubusercontent.com/chloevan/datasets/master/covid_19/covid_19.csv'
covid = pd.read_csv(url)
print(tabulate(covid.head(), tablefmt="pipe", headers="keys"))
|    | dateRep    |   day |   month |   year |   cases |   deaths | countriesAndTerritories   | geoId   | countryterritoryCode   |   popData2018 |
|---:|:-----------|------:|--------:|-------:|--------:|---------:|:--------------------------|:--------|:-----------------------|--------------:|
|  0 | 2020/04/05 |     5 |       4 |   2020 |      35 |        1 | Afghanistan               | AF      | AFG                    |   3.71724e+07 |
|  1 | 2020/04/04 |     4 |       4 |   2020 |       0 |        0 | Afghanistan               | AF      | AFG                    |   3.71724e+07 |
|  2 | 2020/04/03 |     3 |       4 |   2020 |      43 |        0 | Afghanistan               | AF      | AFG                    |   3.71724e+07 |
|  3 | 2020/04/02 |     2 |       4 |   2020 |      26 |        0 | Afghanistan               | AF      | AFG                    |   3.71724e+07 |
|  4 | 2020/04/01 |     1 |       4 |   2020 |      25 |        0 | Afghanistan               | AF      | AFG                    |   3.71724e+07 |
covid.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 8905 entries, 0 to 8904
Data columns (total 10 columns):
 #   Column                   Non-Null Count  Dtype  
---  ------                   --------------  -----  
 0   dateRep                  8905 non-null   object 
 1   day                      8905 non-null   int64  
 2   month                    8905 non-null   int64  
 3   year                     8905 non-null   int64  
 4   cases                    8905 non-null   int64  
 5   deaths                   8905 non-null   int64  
 6   countriesAndTerritories  8905 non-null   object 
 7   geoId                    8883 non-null   object 
 8   countryterritoryCode     8824 non-null   object 
 9   popData2018              8873 non-null   float64
dtypes: float64(1), int64(5), object(4)
memory usage: 695.8+ KB

(2) 피벗테이블 만들기

  • 판다스에는 .pivot_table() 함수가 존재한다.
  • 각 국가별로 확진자수를 확인해보는 코드를 작성한다.
cases_by_country = pd.pivot_table(covid, index = 'countryterritoryCode', values = 'cases', aggfunc='sum')
print(cases_by_country)
                      cases
countryterritoryCode       
ABW                      64
AFG                     270
AGO                      10
ALB                     333
AND                     466
...                     ...
VNM                     240
XKX                     126
ZAF                    1585
ZMB                      39
ZWE                       9

[199 rows x 1 columns]
  • 먼저, 각각의 인수를 확인하자.
    • pivot_table() 함수를 사용한다.
    • covid는 데이터를 의미한다.
    • index는 기준점이 되는 변수를 의미하며, 보통 문자열 변수를 작성한다.
    • values는 계산하려는 변수를 의미하며, 보통 숫자열 변수를 작성한다.
    • aggfunc는 기초통계함수가 온다. 여기에서는 sum이 사용되었다. 참고로 default는 평균을 의미하는 mean이 사용된다.

(3) 피벗테이블 정렬

  • 그런데, 정렬이 되어 있지 않으니 깔끔하게 정리된 것 같지가 않다. cases를 기준으로 정렬을 해보자.
cases_by_country2 = cases_by_country.sort_values("cases", ascending=False).reset_index()
print(cases_by_country2)
    countryterritoryCode   cases
0                    USA  312237
1                    ESP  124736
2                    ITA  124632
3                    DEU   91714
4                    CHN   82575
..                   ...     ...
194                  GMB       4
195                  VGB       3
196                  BDI       3
197                  TLS       1
198                  PNG       1

[199 rows x 2 columns]
  • 정렬을 위해서 sort_values()함수를 활용했다.
  • 내림차순으로 할지, 오름차순으로 할지 결정해야 하는데 기본적으로 오름차순으로 세팅이 되어 있기 때문에 내림차순으로 바꾸려면 ascending=False로 한다.
  • 행의 순서를 바꿔줘야 하기 때문에 reset_index()로 지정한다.

(4) Multi Colums

  • 이번에는 casesdeaths를 한꺼번에 구하도록 해보자.
cases_deaths_by_country = pd.pivot_table(covid, index = 'countryterritoryCode', values = ['cases', 'deaths'], aggfunc='sum')
cases_deaths_by_country2 = cases_deaths_by_country.sort_values(["deaths", "cases"], ascending=False).reset_index()
print(cases_deaths_by_country2)
    countryterritoryCode   cases  deaths
0                    ITA  124632   15362
1                    ESP  124736   11744
2                    USA  312237    8501
3                    FRA   68605    7560
4                    GBR   41903    4313
..                   ...     ...     ...
194                  SLE       4       0
195                  BDI       3       0
196                  VGB       3       0
197                  PNG       1       0
198                  TLS       1       0

[199 rows x 3 columns]
  • 무언가 복잡해 보이지만, 크게 달라지는 것은 없다.
  • 다만, 두개 이상의 column을 입력하려면 함수 안에서 대괄호 [column_1, column_2] 형태로 입력해주기만 하면 위와 같은 결과물이 나온다.

(5) Multi Index and Multi Colums

  • casesdeaths를 확인하기 위함이니, values에 입력을 했다. 그러면 확진자수-사망자수 ~ 국가별-월별을 하려면 어떻게 작성해야 할까? values에 적용했던 것처럼 index에 적용 하기만 하면 된다.
cases_deaths_by_country_month = pd.pivot_table(covid, index = ['countryterritoryCode', 'month'], values = ['cases', 'deaths'], aggfunc='sum')
cases_deaths_by_country_month2=cases_deaths_by_country_month.sort_values(["countryterritoryCode", "month", "deaths", "cases"], ascending=True).reset_index()
print(cases_deaths_by_country_month2)
    countryterritoryCode  month  cases  deaths
0                    ABW      3     50       0
1                    ABW      4     14       0
2                    AFG      1      0       0
3                    AFG      2      1       0
4                    AFG      3    140       4
..                   ...    ...    ...     ...
587                  ZAF      4    259       6
588                  ZMB      3     35       0
589                  ZMB      4      4       1
590                  ZWE      3      7       1
591                  ZWE      4      2       0

[592 rows x 4 columns]
  • 각 인수의 의미는 동일하다. 다만, 정렬 순서만 조금 바뀌었는데, 8905개의 데이터가 깔끔하게 요약된 것을 확인할 수 있다.
  • countryterritoryCode에서 원하는 데이터를 필터를 해서 국가별로 비교할 수도 있고, 그래프를 작성할 수도 있다.

III. 결론

피벗 테이블은 위대하다. 데이터를 다루는 모든 Tool에 기본적으로 pivot 테이블 기능이 들어가 있다. 피벗 테이블을 활용하면 깔끔한 보고서를 만드는데 매우 훌륭한 기초자료가 될 수 있다.

위 데이터는 참고로 4/6일까지의 데이터이기 때문에 한달이 지난 시점 어떻게 바뀌었는지 비교 분석하는 것은 독자의 몫으로 남겨둔다.

그러나, 아직까지는 파이썬 내에서만 확인이 가능하며, 이를 엑셀로 내보내는 작업이 남는다. 엑셀로 내보내는 것은 결과물이며, 이를 바탕으로 의사결정을 수립하는데 있어서 매우 훌륭한 기초자료가 될 수 있기 때문이다.

다음 포스트에서는 피벗테이블과 그래프를 작성하여 엑셀로 내보내는 것까지의 과정을 담아보도록 한다.

It’s your turn. Learn by doing.

IV. Reference

Piepenbreier, N. (2020, April 16). A Step-by-Step Guide to Pandas Pivot Tables. Retrieved from https://towardsdatascience.com/a-step-by-step-guide-to-pandas-pivot-tables-e0641d0c6c70


  1. 데이터 소스는 EU Opne Data PortalCOVID-19 Coronavirus data에서 가져왔고 그중 일부를 csv로 변환하여 github에 보관했다. ↩︎