Python for Process Innovation
#Python, #Javascript, #SAP, #Automation, #ML, #AI
다트 전자공시시스템, 오랜만에 홈페이지에 가 보니, 대한민국 기업정보의 창이라는 로고 위의 작은 문구가 눈에 띄는군요. 언제부터인지 정확히 기억은 나지 않지만, 이 곳에서는 금융업을 제외한 상장법인의 재무제표를 텍스트파일 형태로 제공하고 있습니다(제가 발견한 것은 2~3년 전으로 기억합니다.).
IFRS XBRL 편집기를 통해 제출된 데이터라고는 하지만 아직 모든 기업들이 IFRS 표준 계정과목으로 통일된 자료로 제출되는 것이 아니기 때문에 이를 효과적으로 이용하기 위해서는 당연히 사전 가공이 필요하며, 여느 미가공 데이터 처럼 그 구조와 각종 예외를 파악하기 위해선 다소의 시간과 노력이 필요합니다.
아래 코드는 주요 재무비율들과 관련된 IFRS 계정들의 소위 '가지고 놀아볼 만한' 수준의 1차 가공을 할 수 있는 간단한 코드이며, 이를 통해 오토인코더, t-SNE 등 다양한 재미있는 것들을 해 보실 수 있을 것입니다. 제 경우엔 나중에 실제로 신규 고객 재무제표 평가(기업간 비교를 통한 SAP Credit Limit 산정) 관련 업무에 적용 하여 나름 괜찮은 결과를 얻기도 했습니다.
코드에는 2016년도 사업보고서를 대상으로 하고 있지만 제가 사용해본 결과 2015, 2017, 2018 재무제표를 대상으로 모두 사용 가능 합니다. 물론 데이터의 무결성 요구 등에 따라 제거되는 기업이 있을 수 있다는 점을 참고하시고 필요하다면 수정해서 사용하시기 바랍니다.
import pandas as pd
# engine='python'은 pd.read_table의 CParserWrapper 관련 문제를 우회하기 위한 설정
bs = pd.read_table('2016_사업보고서_01_재무상태표_20170524.txt', delimiter='\t', encoding='cp949', engine='python')
pl = pd.read_table('2016_사업보고서_02_손익계산서_20170524.txt', delimiter='\t', encoding='cp949', engine='python')
pl_i = pd.read_table('2016_사업보고서_03_포괄손익계산서_20170524.txt', delimiter='\t', encoding='cp949', engine='python')
pl = pd.concat([pl, pl_i])
bs = bs.drop(['재무제표종류', '시장구분', '업종', '결산월', '보고서종류'], axis=1).dropna(how='all', axis=1)
bs = bs[~bs['항목명'].str.contains('abstract')]
pl = pl.drop(['재무제표종류', '시장구분', '업종', '결산월', '보고서종류'], axis=1).dropna(how='all', axis=1)
pl = pl[~pl['항목명'].str.contains('abstract')]
bs_ifrs = bs[bs['항목코드'].str.contains('ifrs_')].copy()
pl_ifrs = pl[pl['항목코드'].str.contains('ifrs_|dart_')].copy()
for e in ['당기', '전기', '전전기']:
bs_ifrs[e] = bs_ifrs[e].str.replace(',', '').astype(float)
pl_ifrs[e] = pl_ifrs[e].str.replace(',', '').astype(float)
#bs_ifrs.head(3)
bs_prin = bs_ifrs[bs_ifrs['항목코드'].isin([
'ifrs_Assets',
'ifrs_Liabilities',
'ifrs_Equity',
'ifrs_CurrentAssets',
'ifrs_CurrentLiabilities',
'ifrs_TradeAndOtherCurrentReceivables',
'ifrs_OtherCurrentFinancialAssets',
'ifrs_CashAndCashEquivalents'])].drop(['항목명'], axis=1)
#bs_prin.head(3)
pl_prin = pl_ifrs[pl_ifrs['항목코드'].isin([
'ifrs_Revenue',
'ifrs_FinanceCosts',
'ifrs_ProfitLoss',
'dart_OperatingIncomeLoss'])].drop(['항목명'], axis=1)
#pl_prin.head(3)
consol_ = pd.concat([bs_prin, pl_prin])
consol = pd.pivot_table(consol_, values='당기', columns='항목코드', index='종목코드')
consol_py = pd.pivot_table(consol_, values='전기', columns='항목코드', index='종목코드')
consol[['ifrs_FinanceCosts', 'ifrs_Revenue']] = consol[['ifrs_FinanceCosts', 'ifrs_Revenue']].fillna(0)
consol_py[['ifrs_FinanceCosts', 'ifrs_Revenue']] = consol_py[['ifrs_FinanceCosts', 'ifrs_Revenue']].fillna(0)
consol = consol.dropna(how='any')
consol_py = consol_py.dropna(how='any')
#consol.head(3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56