2019.07.05 Apply 메소드를 통한 데이터프레임의 값 Update (2)
지난 이야기입니다.
금융 데이터 분석을 위해 데이터프레임을 다루고 있던 저는, 데이터프레임
내부의 수많은 데이터를 수정해야 함을 알게 되어 그만 정신을 잃고 말았습니다. 하지만 apply라는 강력한 모듈이 있다는 것을 알고, 힘을 내어 다시 일어나 코딩을 다짐하게 되는데…
제가 예시로 다루고 있는 코드는 다음과 같습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| k10=pd.DataFrame(columns=stock_dict['기업명'])
for idx,code in enumerate(code_list):
aa=getStockPrice(code)
aa['close']=pd.to_numeric(aa['close'])
stock_all=int(stock_dict['주식 발행 수'][idx])
cRatio=float(stock_dict['유동 비율'][idx])
aa['close']=aa['close'].apply(lambda x:x*cRatio*stock_all)
k10[stock_dict['기업명'][idx]]=aa['close']
k10
|
간단히 설명을 드리자면, KOSPI200처럼 KOSPI10을 구현해보려는 코드 입니다. 자세한 설명은 이전
글을 참고해주세요.
어제 to_numeric 함수까지 설명을 드렸습니다. 다음 코드 그대로 이어 나가겠습니다.
1
| stock_all=int(stock_dict['주식 발행 수'][idx])
|
주식 정보가 들어있는 딕셔너리에서 주식 발행 수를 읽는 코드입니다.
전에 왜 for문에서 굳이 enumerate를
해서, 인덱스 번호를 추출했느냐 의문을 가졌던 적이 있는데요, 여기서
쓰기 위해 추출했습니다. 좀 더 자세히 설명 드리도록 하겠습니다.
제가 이 코드를 짤 때, 주식 정보 딕셔너리의 Value 값들은 List 형태로 넣었습니다. 그리고 각 List는 인덱스 번호에 맞게 매칭되어 있습니다. 예를 들면 삼성전자의 주식 발행 수는 2019년 7월 4일 현재 기준으로 5,969,782,550주이며, 유동 비율은 74.59%입니다. 네이버 금융 쪽의 정보를 크롤링해 가져왔습니다.
그럼 주식 정보 딕셔너리의 내부를 볼까요? 딕셔너리에는 ‘기업명’, ‘주식 발행 수’, ‘유동
비율’ 이 세 가지 키와 그에 해당하는 List로 구성되어 있습니다. 한번 보도록 할까요?
위의 사진을 보시면 각 리스트들의 값이 매칭되는 것을 확인하실 수 있습니다. 그리고
for문으로 종목 코드로 이루어진 리스트를 이용했는 데, 이
값 또한 딕셔너리의 값들과 매칭됩니다.
말이 길어졌는데요, 제가 code_list 변수의 인덱스를 추출한 이유는, 다른 리스트의 값들을 함께 읽기 위함이었습니다. 각 값이 매칭되도록 리스트를 만들었기 때문에, 무리없이
인덱싱을 할 수 있는 것입니다.
주식 발행 수의 리스트를 인덱싱해 값을 꺼낸 후, int형으로
형 변환을 합니다. 일단 리스트를 만들 때 불필요한 문자열은 다 떼어 내긴 했지만(콤마나 ‘주’ 글자) 형 변환 까지는 미리 해 두질 않아서 ㅎㅎ… 일단 수학적 계산을 해야 하기 때문에 정수형으로 전환했습니다.
1
| cRatio=float(stock_dict['유동 비율'][idx])
|
유동 비율도 전의 코드와 동일합니다. 유동 비율 리스트를 인덱싱 한
후 형 변환을 합니다. 다만 유동 비율의 경우 실수 형이기 때문에 float 형으로 바꿔주었습니다.
1
| aa['close']=aa['close'].apply(lambda x:x*cRatio*stock_all)
|
이제야 나왔습니다. 대망의 apply
메소드입니다. 이 메소드 하나를 설명하기 위해 먼 길을 걸어왔습니다. 설명 시작하겠습니다.
apply 함수는
매개값으로 func, 즉 함수를 받습니다. 추가로
행 값을 바꿀 지 열 값을 바꿀지 지정하는 axis나 함수에 들어오는 값 처리를 Series 타입으로 할 지 ndarray로 할 지 지정할 수 있는 raw 등 다양한 파라메터가 있으나, 여기서는 함수 매개 값만 이용하도록
하겠습니다. 자세한 파라메터는 Documentation을
확인하시기 바랍니다.
apply에 함수가 들어가게 되면, 데이터프레임 내의 값들을 함수에 적용하여 리턴 합니다. 반복문은
쓸 필요 없습니다. 알아서 일괄 처리해주거든요.
여기서 포인트는, 함수를 따로 선언하지 않았다는 것입니다. lambda 형식으로 함수를 간결하게 만들었습니다.
간단히 설명 드리자면, apply가 매개 값으로 받은 함수는 ‘lambda 인자 : 표현식’으로
구성되어 있습니다. 인자는 aa[‘close’], 즉 종가 Series
입니다. 하지만 Series 전체가 통째로 들어
가기 보다는, 값 하나하나가 인자로 적용된다는 느낌으로 아시면 좀 더 수월하게 이해할 수
있을 것입니다.
값 하나가 인자로 들어오게 되면, 표현식의 계산대로 값이 갱신됩니다. 이 코드의 경우, 기업의 수정 주가 데이터프레임에서 ‘종가’ 열만 값을 갱신하도록 합니다. 목표는 일일 시가총액이기 때문에, 주식 발행 수 * 유동 비율 * 주가(종가)로 계산합니다. 결과는 새로 데이터프레임을 만든 다음에 보여드리도록 하겠습니다.
1
| k10[stock_dict['기업명'][idx]]=aa['close']
|
전에 만들어 둔 K10 데이터프레임에 수정한 값들을 한
줄 한 줄 넣어줍니다.
k10 안에 매개 값으로 넣은 stock_dict[‘기업명’]은 다들 알다시피 주가 정보 딕셔너리
중에서 ‘기업명’ 키와 연결된 값을 가져옵니다. 지금의 경우에는 기업명이 담긴 리스트를
불러오겠죠. 그리고 뒤에 붙은 [idx]는 그
리스트를 인덱싱 하는 코드로, 아까 말씀드린 대로 제가 따온 모든 주식 데이터 들은 리스트의
인덱스가 동일하게 매칭 되기 때문에, 무리없이 enumerate로
추출한 인덱스를 이용할 수 있는 것입니다.
그 동안 구구절절 설명을 읽으며 오느라 고생하셨습니다! 이제 결과값을
출력하겠습니다. 데이터프레임의 상위 5개와 하위 5개의 값입니다.
값이 이쁘게 나온 것을 확인 할 수 있습니다.
이후에 데이터프레임 인덱스를 각 값의 관련 날짜로 변환하고, sum()을 이용해 기업들의 일일 시가총액 총합을 계산하고, 그에 대한 지수를 구하는 등 다양한 절차를 거치긴 하는데, 그건
스킵하겠습니다. 이번 글은 어디까지나 apply 매크로에 대해 설명하는 것이 목표였으니까요.
apply 메소드를 처음보고 머리가 띵했습니다. 굳이 반복문을 쓰지 않고도 값을
갱신할 수 있다니. 그 뒤로 데이터프레임을 쓸 때 마다 어떻게든 apply를 써 보려고 발버둥쳤던 걸로 기억합니다. 지금은 자제하고
있지만요.
하지만 아쉬운 건, apply
함수에 대한 설명을 블로그에 올리려고 할 때, 사례가 되는 코드를 잘못 선정한 것
같은 느낌이 강했다는 겁니다. 이 함수를 설명하기
위해 글을 두 페이지로 나눴을 뿐더러, apply에 대한 설명은 글에 비해 그리 많지 않습니다. 다음에 이러한 글을 올리게 된다면, 따로 예시 코드를 만드는 게
더 효과적일 것이라 생각됩니다.
그래도 apply 말고도
다른 함수들을 많이 소개했으니 추가로 공부한 셈 치고자 합니다. 그리고 다음에 공부할 때, 머리에 번개가 칠 만한 좋은 코드를 발견하게 되었으면 좋겠습니다.





댓글
댓글 쓰기