엑셀 보다 파이썬! 판다스를 배워보자
업데이트:
파이썬의 본격 시작, 판다스
1) 파이썬의 핵심 데이터 분석 도구
판다스(pandas)는 파이썬을 활용해 데이터를 다루는 프로젝트라면 어디든 빠지지 않고 등장하는 유명 라이브러리이다. 외부 데이터의 추출과 정제, 가공, 통계분석, 시각화까지 데이터 분석에 필요한 대부분의 기능들을 가지고 있다.
최근 빅데이터가 주목을 받으며 관련 파이썬 라이브러리들이 생겨나고 있는데, 많은 경우 판다스의 데이터 형식과 구조에 의존하고 있다. 파이썬 기반의 데이터 분석 분야에서는 판다스가 가장 기본적이고 핵심적인 위치에 있다고 할 수 있다.
Pandas 홈페이지(pandas.pydata.org), 팬더곰과는 관련이 없다고 한다(!) |
2) 엑셀이 답답해지는 순간, 코딩의 세계로
어떤 직종이든 숫자를 다뤄야하는 사무직이라면 실무의 알파이자 오메가는 엑셀 작업일 것이다. 엑셀은 우수한 데이터 분석/관리 도구임에 틀림없다. 그럼에도 엑셀은 ‘무겁다’. 데이터의 양이 일정 수준을 넘어가면 버벅거리고 느려지기 시작한다. 또한 데이터를 가공하고 분석하는 로직이 복잡할 수록 사용하기가 어려워진다. 수없이 시트를 만들고 셀마다 함수로 도배를 하게 된다.
여기서 만약 로직이나 핵심적인 변수들이 바뀌게 되면 더 골치가 아프다. 같은 파일을 하나 더 만들어서 시트를 하나씩 열어보며 다시 가공/분석 작업을 수행해야 한다. 대용량 데이터에 대해 다양한 케이스 분석을 해야한다면 수십메가짜리 엑셀파일이 수십개씩 쌓여나가게 된다.
빅데이터의 시대에 접어들면서 우리 사무직들이 다뤄야할 데이터의 양과 복잡도는 점차 늘어나게 될 것이다. 물론 소규모의 단순한 분석 수준의 반복 작업에서는 앞으로도 엑셀의 효율성을 대체하긴 어려울 것이다. 하지만 엑셀이 가끔 동작을 멈추고 vlookup과 피벗테이블로도 해결이 안되는 문제에 직면했을 때가 바로 엑셀 대신 파이썬을 요청해야 하는 순간이다.
3) 직장인 코딩의 첫 걸음은 판다스로부터
판다스는 엑셀로 할 수 있는 거의 모든 일을 대체할 수 있다. 게다가 더 간단하고, 빠르게 작업이 가능하다. 심지어 파이썬의 다른 라이브러리들과 연계해 업무 자동화, 고급 통계분석 등으로 이어나갈 수도 있다. 실무에 직접 도움이 되는 직장인 코딩은 판다스에서부터 본격적으로 시작된다.
판다스를 쓴다고 해서 엑셀을 버릴 수 있는 것은 아니다. 여전히 회사의 업무시스템은 엑셀 베이스로 데이터를 제공하고 있을 것이고, 아마도 내가 아닌 모든 동료들과의 공동작업은 엑셀로 할 수 밖에 없는 환경이다.
그럴 때는 가장 날것의 데이터와 양식들만 엑셀로 남겨두고, 연산과 분석 작업을 코딩으로 수행하면 된다. 수없이 많은 보조시트와 함수들을 단 몇줄의 코드로 대체할 수 있다. 로직이 바뀌어도 해당되는 핵심코드만 바꿔 끼우면 쉽게 변용이 가능하다. 같은 작업이 매일 반복된다면 금상첨화다. 엔터 한번으로 모든 것을 자동화 할 수도 있다.
판다스 맛보기
본격적으로 판다스를 공부하기 전에, 간단한 예시들을 맛보기로 경험해보자. 연습삼아 주피터 노트북을 켜고 코드를 따라 치면서 결과를 확인해볼 수 있을 것이다. 너무 간단한 예시만 들어서 ‘엑셀로 하는게 더 낫겠다’는 생각이 들텐데, 섣불리 실망하지 않기를 바란다. 앞으로 갈길이 멀다!
1) 판다스 설치 및 불러오기
아나콘다(Anaconda)를 사용한다면 판다스가 기본으로 장착돼있으므로 별도의 설치과정이 필요 없다. 표준 파이썬을 사용하거나 가상환경을 만든다면 다음과 같이 판다스를 설치하면 된다. 참고로 주피터 노트북에서 느낌표(!)를 앞에 붙이면 명령프롬프트(cmd창)에서의 명령어를 사용할 수 있다.
pip install pandas # cmd 창 또는 터미널에서 입력할 경우
pip install pandas --upgrade # 설치된 상태에서 버전을 업그레이드 하는 경우
!pip install pandas # 주피터 노트북에서 입력할 경우
판다스 라이브러리를 사용하려면 우선 임포트(import)를 해야한다. 판다스는 pd 라는 별칭으로 임포트하는 것이 전세계적인 관례이므로 따르도록 하자. 아래와 같이 판다스의 버전을 확인해보자. 구버전일 경우 업그레이드를 해주자 (2021.2.21 현재 1.2.2 가 최신)
import pandas as pd # 라이브러리 임포트
pd.__version__ # 버전 확인
'1.2.2'
2) 엑셀 파일에서 데이터 읽어오기
원본 데이터를 담고 있는 엑셀파일(내려받기)은 다음과 같다. 코스피와 코스닥에 상장된 기업들의 과거 10년간의 매출액, 영업이익, 당기순이익과 섹터 정보를 담은 자료이다. 총 22,600개의 행(row)과 7개의 열(column)로 구성돼있다.
패널자료_2010_2019. 코스피코스닥.xlsx |
이 데이터를 판다스 명령어를 통해 파이썬 환경으로 불러오자
data = pd.read_excel('패널자료_2010_2019_코스피코스닥.xlsx')
data
종목코드 | 종목명 | 연도 | 매출액(천원) | 영업이익(천원) | 당기순이익(천원) | 섹터 | |
---|---|---|---|---|---|---|---|
0 | A005930 | 삼성전자 | 2010 | 1.546303e+11 | 1.662103e+10 | 1.614652e+10 | 반도체 |
1 | A005930 | 삼성전자 | 2011 | 1.650018e+11 | 1.564429e+10 | 1.375904e+10 | 반도체 |
2 | A005930 | 삼성전자 | 2012 | 2.011036e+11 | 2.904934e+10 | 2.384528e+10 | 반도체 |
3 | A005930 | 삼성전자 | 2013 | 2.286927e+11 | 3.678501e+10 | 3.047476e+10 | 하드웨어 |
4 | A005930 | 삼성전자 | 2014 | 2.062060e+11 | 2.502507e+10 | 2.339436e+10 | 하드웨어 |
... | ... | ... | ... | ... | ... | ... | ... |
22595 | A352820 | 빅히트 | 2015 | NaN | NaN | NaN | NaN |
22596 | A352820 | 빅히트 | 2016 | 3.522050e+07 | 1.038005e+07 | 9.008618e+06 | NaN |
22597 | A352820 | 빅히트 | 2017 | 9.240176e+07 | 3.254540e+07 | 2.456881e+07 | NaN |
22598 | A352820 | 빅히트 | 2018 | 3.013718e+08 | 7.993060e+07 | -7.046558e+07 | NaN |
22599 | A352820 | 빅히트 | 2019 | 5.872245e+08 | 9.874247e+07 | 7.242410e+07 | NaN |
22600 rows × 7 columns
3) 필터링 / 정렬하기
LG전자의 2015년 이후의 자료만 뽑아서 연도 역순으로 정렬을 해보자.
condition = (data.종목명 == 'LG전자') & (data.연도 >= 2015)
lg = data[condition].sort_values(by='연도', ascending=False)
lg
종목코드 | 종목명 | 연도 | 매출액(천원) | 영업이익(천원) | 당기순이익(천원) | 섹터 | |
---|---|---|---|---|---|---|---|
11439 | A066570 | LG전자 | 2019 | 6.230618e+10 | 2.436139e+09 | 1.799480e+08 | 내구소비재 및 의류 |
11438 | A066570 | LG전자 | 2018 | 6.134166e+10 | 2.703291e+09 | 1.472814e+09 | 내구소비재 및 의류 |
11437 | A066570 | LG전자 | 2017 | 6.139628e+10 | 2.468549e+09 | 1.869518e+09 | 내구소비재 및 의류 |
11436 | A066570 | LG전자 | 2016 | 5.536703e+10 | 1.337763e+09 | 1.263150e+08 | 내구소비재 및 의류 |
11435 | A066570 | LG전자 | 2015 | 5.650901e+10 | 1.192291e+09 | 2.491430e+08 | 디스플레이 |
4) 피벗테이블
행에는 연도별, 열에는 섹터별로 구분해 해당 기업들의 영업이익 합계를 보여주는 피벗테이블을 생성해보자
pivot = data.pivot_table(values='영업이익(천원)', index = '연도', columns='섹터', aggfunc='sum')
pivot
섹터 | 기타금융 | 내구소비재 및 의류 | 디스플레이 | 미디어 | 반도체 | 보험 | 부동산 | 상업서비스 | 생활용품 | 소비자 서비스 | ... | 유틸리티 | 은행 | 음식료 및 담배 | 의료 장비 및 서비스 | 자동차 및 부품 | 자본재 | 제약 및 바이오 | 증권 | 통신서비스 | 하드웨어 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
연도 | |||||||||||||||||||||
2010 | 1.402077e+09 | 2.944675e+09 | 2.436067e+09 | 3.826167e+08 | 2.028361e+10 | 4.249219e+09 | -5.692247e+07 | 6.225229e+08 | 1.189731e+09 | 1.222803e+09 | ... | 3.198684e+09 | 6.979284e+09 | 5.074602e+09 | 7.898370e+07 | 1.414171e+10 | 1.984304e+10 | 1.660456e+09 | 1.545113e+09 | 4.720252e+09 | 1.870261e+09 |
2011 | 4.338564e+08 | 2.017018e+09 | -2.398353e+08 | 5.612712e+08 | 1.678310e+10 | 4.530638e+09 | 5.916126e+07 | 6.823309e+08 | 1.265394e+09 | 1.297582e+09 | ... | 4.043390e+08 | 1.207904e+10 | 4.861143e+09 | 7.420770e+07 | 1.759945e+10 | 1.623375e+10 | 1.491778e+09 | 1.582784e+09 | 4.324472e+09 | 1.496819e+09 |
2012 | 9.499003e+08 | 1.558786e+09 | 1.288646e+09 | 7.917403e+08 | 2.956363e+10 | 4.830134e+09 | 5.729134e+07 | 7.970500e+08 | 1.441707e+09 | 1.270034e+09 | ... | 1.078467e+09 | 1.014047e+10 | 5.226630e+09 | 8.797397e+07 | 1.881736e+10 | 1.140954e+10 | 1.261153e+09 | 9.774022e+08 | 3.068342e+09 | 3.413049e+09 |
2013 | 3.282670e+08 | 1.722981e+09 | 3.016177e+09 | 7.030213e+08 | 3.957123e+09 | 3.009804e+09 | 9.528742e+07 | 6.161014e+08 | 1.441739e+09 | 1.228534e+09 | ... | 3.666296e+09 | 7.779141e+09 | 4.701856e+09 | 1.853633e+08 | 1.931532e+10 | 3.912393e+09 | 1.396425e+09 | -9.970465e+07 | 3.399636e+09 | 3.874400e+10 |
2014 | 1.028046e+09 | 1.864722e+09 | 3.558197e+09 | 6.471227e+08 | 6.008643e+09 | 4.653864e+09 | 8.111735e+07 | 6.491948e+08 | 1.890226e+09 | 1.182185e+09 | ... | 7.381537e+09 | 8.612867e+09 | 5.322884e+09 | 1.665123e+08 | 1.822650e+10 | 4.275238e+09 | 1.562700e+09 | 1.330831e+09 | 2.019918e+09 | 2.613542e+10 |
2015 | 6.558617e+08 | 2.088120e+09 | 3.345029e+09 | 8.234777e+08 | 6.518309e+09 | 5.287695e+09 | 1.186583e+08 | 9.966161e+08 | 2.795738e+09 | 1.413629e+09 | ... | 1.297556e+10 | 8.582198e+09 | 6.207576e+09 | 2.434121e+08 | 1.680211e+10 | 1.587474e+09 | 2.033145e+09 | 2.502278e+09 | 3.646648e+09 | 2.762514e+10 |
2016 | 6.968253e+08 | 3.313054e+09 | 1.942677e+09 | 7.699622e+08 | 4.597680e+09 | 5.332493e+09 | 2.545526e+08 | 1.267140e+09 | 3.373968e+09 | 1.525731e+09 | ... | 1.346024e+10 | 9.343782e+09 | 6.658820e+09 | 2.970801e+08 | 1.597699e+10 | 1.180827e+10 | 1.696073e+09 | 1.734491e+09 | 3.730430e+09 | 2.931299e+10 |
2017 | 8.717716e+08 | 4.940874e+09 | 3.671457e+09 | 7.763464e+08 | 1.601460e+10 | 7.809635e+09 | 3.694350e+08 | 5.491872e+08 | 2.788962e+09 | 1.230273e+09 | ... | 6.553649e+09 | 1.400350e+10 | 6.777083e+09 | 2.733390e+08 | 1.001525e+10 | 1.669612e+10 | 2.244993e+09 | 4.341085e+09 | 3.745894e+09 | 5.593330e+10 |
2018 | 8.087551e+08 | 5.481685e+09 | 9.536465e+08 | 1.049645e+09 | 2.318075e+10 | 7.701115e+09 | 4.165879e+08 | 7.074463e+08 | 2.559772e+09 | 1.028330e+09 | ... | 1.603319e+09 | 1.605634e+10 | 4.711524e+09 | 2.299851e+08 | 8.332036e+09 | 1.777192e+10 | 1.667900e+09 | 4.558544e+09 | 3.211307e+09 | 6.216125e+10 |
2019 | 9.081723e+08 | 6.105800e+09 | -9.898823e+08 | 1.155878e+09 | 4.595345e+09 | 4.770805e+09 | 3.379355e+08 | 1.073942e+09 | 2.437352e+09 | 1.129512e+09 | ... | 6.099816e+08 | 1.979920e+10 | 4.638856e+09 | 3.487813e+08 | 1.112191e+10 | 1.563592e+10 | 1.621191e+09 | 5.842008e+09 | 2.928385e+09 | 3.128180e+10 |
10 rows × 25 columns
5) 시각화
위에서 생성한 피벗테이블 중에서 ‘자동차 및 부품’ 산업과 ‘자본재’ 산업의 영업이익의 시계열 그래프를 그려보자
pivot[['자동차 및 부품', '자본재']].plot()
댓글남기기