ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 달러인덱스와 환율의 상관계수 및 그래프 그리기
    ESG부트캠프/판다스 입문 2022. 10. 4. 09:26
    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
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    import pandas as pd
    import matplotlib.pyplot as plt
    import numpy as np
    import matplotlib
     
    matplotlib.rcParams["font.family"= "Malgun Gothic"            # 한글, -깨짐방지
    matplotlib.rcParams["font.size"= 15.0                         # 플롯 기본 폰트사이즈 설정
    matplotlib.rcParams["axes.unicode_minus"= False
     
     
    dollar_index = pd.read_csv("C:\PycharmProjects\달러인덱스전체.csv", encoding="UTF-8")  # 달러인덱스 데이터 읽어옴
    dollar_index = dollar_index.drop(columns=["Unnamed: 0"])                            # 이상한 컬럼 붙어있어서 지움
     
    krw_dollar = pd.read_csv("C:\PycharmProjects\환율전체.csv", encoding="UTF-8")   # 환율 데이터 읽어옴
    krw_dollar.dropna(inplace=True)                                               # 결측데이터 행 제거
    krw_dollar["환율"= krw_dollar["환율"].str.replace(",""")                    # 천단위 ,기호 제거
    krw_dollar.rename(columns = {"날짜" : "Date"}, inplace=True)                   # merge시의 편의를 위해 컬럼명을 Date로 통일
    krw_dollar["환율"= pd.to_numeric(krw_dollar["환율"], errors = "coerce")       # str->int로 타입변환
    krw_dollar.reset_index(inplace=True, drop=True)                               # 인덱스 초기화
     
     
    entire = pd.merge(dollar_index, krw_dollar, how = "inner")                    # 달러인덱스와 환율을 Date를 기준으로 병합
    entire.reset_index(inplace=True, drop=True)                                   # inner로 병합했으니 인덱스 초기화
    entire.rename(columns = {"Close" : "Dollar index"}, inplace=True)
     
     
    for i in entire.index:          # 전일대비환율변화율을 구함. 변화율이 0인경우 /가 안되기때문에 에러 발생하므로 if문으로 케이스 분류
        try:                        # entire.index라서 인덱스 끝에서 한번 더 실행되는데 이때 에러 무시하기 위해 except-break
            i += 1
            if entire.loc[i, "환율"!= entire.loc[i-1"환율"]:
                entire.loc[i, "전일대비환율변화율"= (entire.loc[i, "환율"- entire.loc[i-1"환율"]) / entire.loc[i-1"환율"]
            else:
                entire.loc[i, "전일대비환율변화율"= 0
        except:
            break
    entire.dropna(inplace = True)
    entire.reset_index(inplace = True, drop = True)
    q1_c_ratio = entire["전일대비환율변화율"].quantile(0.25)         # 1사분위값
    q2_c_ratio = entire["전일대비환율변화율"].quantile(0.5)          # 2사분위값
    q3_c_ratio = entire["전일대비환율변화율"].quantile(0.75)         # 3사분위값
    iqr_c_ratio  = q3_c_ratio - q1_c_ratio                       # 박스 범위를 3사분위값-1사분위값으로 설정
     
    upper_abnormal = entire["전일대비환율변화율"]>q3_c_ratio+1.5*iqr_c_ratio     # 윗쪽 이상치 제거
    upper_abnormal_index = entire[upper_abnormal].index
    entire.drop(upper_abnormal_index, inplace=True)
     
    lower_abnormal_c_ratio = entire["전일대비환율변화율"]<q1_c_ratio-1.5*iqr_c_ratio     # 아랫쪽 이상치 제거
    lower_abnormal_index_c_ratio = entire[lower_abnormal_c_ratio].index
    entire.drop(lower_abnormal_index_c_ratio, inplace=True)
     
    entire.reset_index(inplace=True, drop=True)         # 이상치 제거했으니 인덱스 리셋
     
    for i in entire.index:      # 위와 같음
        try:
            i += 1
            if entire.loc[i-1"Dollar index"!= entire.loc[i, "Dollar index"]:
                entire.loc[i, "전일대비달러인덱스변화율"= (entire.loc[i, "Dollar index"- entire.loc[i-1"Dollar index"]) / entire.loc[i-1"Dollar index"]
            else:
                entire.loc[i, "전일대비달러인덱스변화율"= 0
        except:
            break
     
    q1_d = entire["전일대비달러인덱스변화율"].quantile(0.25)    # 위와 같음
    q2_d = entire["전일대비달러인덱스변화율"].quantile(0.5)
    q3_d = entire["전일대비달러인덱스변화율"].quantile(0.75)
    iqr_d  = q3_d - q1_d
     
    upper_abnormal_d = entire["전일대비달러인덱스변화율"]>q3_d+1.5*iqr_d
    upper_abnormal_index_d = entire[upper_abnormal_d].index
    entire.drop(upper_abnormal_index_d, inplace=True)
     
    lower_abnormal_d = entire["전일대비달러인덱스변화율"]<q1_d-1.5*iqr_d
    lower_abnormal_index_d = entire[lower_abnormal_d].index
    entire.drop(lower_abnormal_index_d, inplace=True)
     
     
    entire.dropna(inplace=True)
    entire.reset_index(inplace=True, drop=True)
    entire = entire.drop(["전일대비환율변화율""전일대비달러인덱스변화율"], axis = "columns")
     
     
     
    entire = entire[8092:8256]              # 구하고자 하는 구간의 범위를 설정하는 곳
    corr = entire.corr(method = "pearson")      # 피어슨 상관계수 구하기
    #imf 3713:4024          # 확인하기 귀찮아서 메모해놓은 구간 인덱스
    #지금 8092:8256
     
    # 산포도 그리고 싶으면 이걸 쓰세요
    '''entire.plot(kind='scatter',x="환율",y="Dollar index")
    plt.show()'''
     
     
     
    plt.rcParams["figure.figsize"= (30,13)
    plt.rcParams["lines.linewidth"= 2         #플롯 내 선 굵기
     
    x1 = entire["Date"]
    y1 = entire["Dollar index"]
     
    x2 = entire["Date"]
    y2 = entire["환율"]
     
    plt.title("달러인덱스 & 환율", size = 20)
    plt.xlabel("날짜", fontdict = {"size" : 15})
    plt.xticks(np.arange(0len(entire.index)+18), rotation = 45)
    ax = plt.plot(x1, y1, color = "black", label = "달러인덱스")
    plt.ylabel("달러인덱스", color = "black", fontdict = {"size" : 15})
    plt.tick_params(axis = "y", labelcolor = "black")
     
    y_right = plt.twinx()
    plt.xticks(np.arange(0len(entire.index)+18), rotation = 45)
    ax2 = y_right.plot(x2, y2, color = "red", label = "환율")
    plt.ylabel("환율", color = "red", fontdict = {"size" : 15})
    y_right.tick_params(axis = "y", labelcolor = "red")
     
    plt.legend(handles = ax + ax2, loc = "best")
     
    plt.show()
    cs

     

    처음 데이터셋으로 받아온 달러인덱스와 환율에서 이상치를 제거하기 위해 각 항목의 전일대비변동률을 따로 구해준 뒤, 변동률을 기준으로 박스플롯을 이용해 이상치를 제거하였다.

     

    달러인덱스와 환율이 일 단위 시간변화에 따라 연속적인 값을 가지는 데이터기 때문에 원데이터에서 이상치를 제거하면

     

    첫째로 위에서 구현한 코드대로라면 상관계수를 구하거나 그래프를 그리는 과정에서 시간변화를 고려하지 않기 때문에 절대적으로 값의 낮고 높음만으로 이상치를 판단하게 됨

    둘째로 연속적인 값임을 고려하지 않기 때문에 한 구간을 이상치로 판단하여 제외하게 되면 그 다음 구간도 높은 확률로 이상치가 되어 어떤 특정 구간이 통째로 이상치로 판단되어 날아감

    와 같은 문제가 발생하기 때문이다.

     

     

    또 그래프 그릴 때 각각의 y축 값을 따로 설정하는 과정에서 좀 헤맸는데

    x-y1의 그래프(위에선 ax)와 x-y2의 그래프(위에선 ax2)를 그리고 plt.twinx()로 각각의 그래프가 x축을 공유하도록 설정해주면 된다.

    이 때 범례를 x-y1, x-y2에서 따로 잡아주면 같은 위치에 겹쳐서 그려지는데, x축을 공유하도록 설정한 후

    plt.legend(handles = ax + ax2, loc = "best")

    이렇게 handles로 범례 표시할 그래프를 잡아주면 알아서 잘 표시해준다.

Designed by Tistory.