3. 튜토리얼/금융 분석 프로그래밍 기초

금융 분석을 위한 파이썬 프로그래밍 - 01. 라이브러리, 데이터프레임, 인덱싱

swsong 2023. 1. 30. 21:57

Step 1. 라이브러리

우리가 개발을 할 때, 모든 코드를 한 땀 한 땀 장인의 정신으로 구현해야 한다면 실력과 무관하게 금세 지쳐버릴 것입니다.

우리가 작성하려고 하는 코드가 매우 정형적이고 일반적으로 자주 쓰이는 것들이라면 누군가는 반드시 함수나 클래스 형태로 이미 구현해두었을 것입니다. 그리고 우리는 이것을 라이브러리라는 형태로 가져와서 쓸 수 있습니다. 심지어 무료로 말입니다.

야후 파이낸스에 있는 주가 정보도 라이브러리라는 것을 사용하면 손쉽게 가져올 수 있습니다. 누군가 이미 그러한 작업을 한 적이 있고, 개발한 코드를 모두가 사용할 수 있게 공개해둔 것이지요. 참고로 아래 이미지, 깃허브라는 코드 저장소에서 실제 구현된 코드를 눈으로 볼 수도 있습니다. yfinance라는 이름의 라이브러리입니다.

이 라이브러리를 사용하고 싶다면 아래와 같이 코드를 작성합니다.

그러면 yfinance 라이브러리를 yf라는 변수명으로 사용할 수 있게 된 겁니다. yfinance는 내부적으로 Tickers라는 클래스를 품고 있습니다. 클래스는 주로 붕어빵 틀로 비유합니다. 붕어빵 틀에서는 붕어빵이 나오죠. 붕어빵을 인스턴스라고 합니다. 비슷하게 우리는 클래스로부터 필요한 인스턴스들을 만들어내고 사용하게 됩니다.

클래스로부터 인스턴스를 만들어낼 때는 경우에 따라 재료를 넣어줍니다. Tickers의 경우 어떤 종목들의 정보를 가져올 것인지, 아래와 같이 괄호 안에 종목 이름들을 재료로 넣어주면 되겠습니다.

우리는 테슬라(TSLA), S&P 500(SPY), NASDAQ100(QQQ)의 주가 정보를 가져오기 위해 3개 티커를 넣어주었습니다. 대괄호로 3개 티커 이름을 감싼 다음에 넣어주었는데, 참고로 이러한 형태의 자료형을 '리스트'라고 부릅니다.

이제 우리는 3개 주가 정보를 다룰 수 있는 stocks라는 인스턴스를 생성한 것입니다. 만약 삼성전자나 카카오 주가 정보를 얻고 싶다면 해당하는 티커를 클래스에 넣어서 새로운 인스턴스를 생성해야 할 것입니다.

인스턴스는 클래스 내부에 정의되어 있는 함수들을 사용할 수 있습니다. 여기서는 history()라는 함수를 사용해 봅니다. history()는 특정 기간의 주가 데이터를 뽑아주는 함수입니다.

history() 함수를 통해 불러온 데이터는 df라는 변수에 담았고, df를 출력해 보면 위와 같이 저장된 데이터 프레임을 보여줍니다. 여기서 데이터 프레임이란 pandas라는 파이썬 데이터 분석 라이브러리에서 제공하는 2차원 자료형의 이름입니다.

왼쪽 날짜(Date) 부분을 데이터 프레임의 인덱스라고 부르고, 위에 Close, Dividends, High, Low 부분을 컬럼이라고 부릅니다. 일반적으로 컬럼과 인덱스는 하나입니다. 그러나 위와 같이 2개가 될 수도 있으며, 이 경우에는 2중 컬럼 형태를 띠는 것입니다. Close라는 칼럼 아래에 QQQ, SPY, TSLA 이렇게 3개의 컬럼이 하나 더 있는 형태입니다.

Step 2. 인덱싱

인덱싱이란 앞에서 봤던 1차원 리스트나 2차원 데이터 프레임 같은 데이터 덩어리로부터 특정 데이터만 추출하는 행위를 말합니다. 인덱싱 방법은 매우 다양하며 일반적으로 쓰이는 방법들을 소개해 드리겠습니다.

2-1. 열 인덱싱

데이터 프레임은 행과 열로 이루어진 2차원 자료형입니다. 만약 특정 열만 추출하고 싶다면 데이터 프레임 뒤에 대괄호로 컬럼 이름을 써주면 됩니다.

앞에서 언급했지만 df 변수에 담은 데이터 프레임은 이중 컬럼을 가지고 있습니다. Close 컬럼을 인덱싱하게되면 이처럼 Close 컬럼에 포함되어 있는 하위 컬럼(열)들을 추출하게 됩니다.

여기서 다시 한번 열 인덱싱을 수행하면 다음과 같이 SPY 컬럼에 해당하는 데이터만 뽑아낼 수 있습니다.

꼭 하나의 열만 추출할 수 있는 것은 아닙니다. 2개 이상의 컬럼은 대괄호로 감싸서 아래와 같이 추출할 수도 있습니다.

그런데 우리가 종가(Close)만 계속해서 볼 텐데 이렇게 이중으로 인덱싱을 하는 것은 매우 귀찮죠? 이때는 Close 컬럼을 인덱싱한 데이터 프레임을 복사해서 다른 변수에 담아주면 됩니다.

여기서는 copy() 함수를 사용했습니다. 해당 함수를 사용하지 않고 그대로 변수에 넣어줄 수도 있습니다. 그러나 그런 방식은 잘 못 사용하면 이따끔 상당히 난처한 상황이 생길 수도 있습니다. 대입한 변수를 수정했을 때 대입한 대상인 원본 변수가 수정될 수 있기 때문입니다. 데이터 분석을 하다 보면 뭔가 처리를 잘못해서 원본 데이터를 다시 가져다가 써야 할 때가 있는데, 원본이 수정되어버리면 처음부터 데이터를 다시 가져와야 합니다.

한번 코드를 보면서 무슨 말인지 눈으로 확인해 보겠습니다.

잠깐 참고로, 주석(#)에 적힌 객체 참조라는 개념에 대해서는 나중에 한 번은 찾아보시길 권장 드립니다. 프로그래밍이 처음이라면 메모리와 데이터 저장에 대한 개념이 와닿지 않을 수 있지만 알아두면 이러한 현상에 대해 더 이상 마법이라 느껴지지 않을 것입니다.

df_close라는 변수는 기존 데이터 프레임에서 Close 컬럼만 인덱싱한 데이터 프레임을 담고 있습니다. 따라서 df_ref는 해당 데이터 프레임을 그대로 가리키고 있는 꼴이라 생각하시면 되겠습니다. 반면 df_copy는 df_close라는 변수를 복제해서 새로운 데이터 프레임을 만든 것입니다.

그래서 df_close와 df_ref는 같은 데이터 프레임을 다른 변수명으로 담고 있으며, df_copy는 같은 모양(같은 데이터 값)이지만 실제로는 모양만 같고 다른 데이터 프레임(다른 메모리에 저장되어 있는 데이터)을 담고 있게 됩니다.

그래서 아래와 같이 df_close와 같은 데이터 프레임을 가리키고 있는 df_ref를 수정하면 df_close도 동일하게 수정됩니다.

반면 다른 메모리 공간에 저장된 다른 데이터 프레임을 가리키고 있는 df_copy의 경우 변하지 않았습니다.

df_copy를 수정하더라도 마찬가지입니다. drop()을 통해 TSLA 컬럼을 제거한 다음 원본 df_close를 확인하면 그대로 유지되고 있는 것을 볼 수 있습니다. drop() 함수에 대해서는 주석을 참고해 주세요.

2-2. 행 인덱싱

열을 인덱싱한 것처럼 행도 인덱싱할 수 있습니다.

데이터 프레임은 기본적으로 인덱스 순서를 0번부터 인식합니다. 위와 같이 작성하면 0번부터 4번 인덱스(5번째 행)까지 추출하는 것입니다.

앞에서 5개 행을 뽑았다면 마지막 5개 행도 뽑을 수 있습니다.

이렇게 자주 쓰이고, 정형화된 코드의 경우 반드시 함수가 있다고 말씀드렸습니다. 아래와 같이 head(), tail()을 통해 간단하게 인덱싱해볼 수도 있겠습니다.

2-3. 행, 열 동시 인덱싱

위에서 확인한 행 인덱싱, 열 인덱싱을 함께 사용할 수도 있습니다.

그리고 이 케이스 역시 자체 함수를 제공합니다. 함수는 대표적으로 2개가 있습니다.

먼저 인덱스 이름, 컬럼 이름으로 인덱싱하는 loc() 함수입니다.

다음은 n 번째 행, n 번째 열처럼 숫자로 인덱싱하는 iloc() 함수입니다.

지금까지 라이브러리, 데이터 프레임, 그리고 인덱싱까지 간단하게 살펴보았습니다.

처음 프로그래밍을 접하고 파이썬 문법을 익힐 때, 알고리즘이나 자료구조에 대해 어려운 개념과 문법부터 시작하시는 경우가 많습니다. 그러나 여러분의 목표가 데이터 분석이라면 이렇게 데이터를 직접 만져보고 분석해 보면서 필요한 문법들을 채워가시는 편을 더 권장 드립니다.

파이썬 고급 문법과 심지어 컴퓨터 공학 이론까지 다 배우고 데이터 분석으로 넘어오기에는 사실상 무한에 가까울 만큼 양이 너무 많고, 실제로 실무에 계신 숙련된 개발자분들도 평생 배워야 한다고 말합니다. 또 배우는 과정에서 웹 개발을 배운다거나 하는 식의 주객전도되는 경우도 더러 있습니다. 물론 연계성이 강한 개발 특성상 두루 알면 도움은 되겠지만 꼭 거쳐야 하는 과정이라고 보기는 어렵습니다. 차라리 분석이 목표라면 분석에 집중하고 더 빠르고 효율적인 분석을 위해 파이썬이라는 도구를 어떻게 활용할 수 있을까를 고민하며 채워나가시면 됩니다.

분석 난이도와 단계에 따라 그에 맞는 적절한 문법과 효율적인 코딩 방식들이 있습니다. 서버에 대해 알아야 할 때가 오고, 데이터베이스와 자료구조를 디테일하게 이해해야 할 때가 옵니다. 미리 모든 것들은 준비하기보다 그때그때의 분석 단계마다 필요한 것들을 배워나간다면 결국은 분석 역량은 물론 이를 뒷받침하는 탄탄한 개발 스킬까지 갖출 수 있게 될 것입니다.