대상 : 2021년 다소비업체 전력사용량 건물부문 데이터 : 한전 실시간 데이터, 에너지사용량신고 데이터

In [1]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
In [2]:
plt.rcParams['figure.figsize'] = (14, 9)
plt.rcParams['font.family'] = 'Malgun Gothic'
plt.rcParams['font.size'] = 12
plt.rcParams['axes.unicode_minus']
Out[2]:
True
In [3]:
df_b = pd.read_pickle('building_site.pkl')
df_b
Out[3]:
kemc_oldx_code_tite ente dt(날짜) tm(시간) 전력사용량(kWh)
0 IDC(전화국) 1192 2021-01-01 0 5982.48
1 IDC(전화국) 1192 2021-01-01 1 5956.56
2 IDC(전화국) 1192 2021-01-01 2 5949.36
3 IDC(전화국) 1192 2021-01-01 3 5927.76
4 IDC(전화국) 1192 2021-01-01 4 5925.60
... ... ... ... ... ...
6613795 호텔 58967 2021-12-31 19 1473.12
6613796 호텔 58967 2021-12-31 20 1345.68
6613797 호텔 58967 2021-12-31 21 1428.48
6613798 호텔 58967 2021-12-31 22 1286.16
6613799 호텔 58967 2021-12-31 23 1171.20

6613800 rows × 5 columns

In [4]:
def basic_graph(data, sector):
    grp_day = data.groupby('dt(날짜)')['전력사용량(kWh)'].sum() / 1000 # 시간 데이터->일 데이터 변환
    #print(grp_day)

    grp_day.plot()
    plt.ylabel('전력소비량(kWh)')
    plt.xlabel('일(day)')
    plt.suptitle(f'{sector}부문 일일 전력소비량(MWh)')
    plt.grid()
    plt.show()

    # 전체를 날짜, 시간으로 구분 후 요일 및 주 추가
    grp_hour = data.groupby(['dt(날짜)', 'tm(시간)'])['전력사용량(kWh)'].sum() / 1000
    grp_hour = grp_hour.reset_index()
    grp_hour['weekday'] = grp_hour['dt(날짜)'].dt.weekday
    grp_hour['weekofyear'] = grp_hour['dt(날짜)'].dt.weekofyear

    # 시간대별 전력소비량을 산포도 형태의 그래프로 그림
    sns.pairplot(grp_hour, x_vars=['tm(시간)'], y_vars='전력사용량(kWh)', hue='tm(시간)', height=5, plot_kws={'alpha':0.1, 'linewidth':0})
    plt.ylabel('전력소비량(MWh)')
    plt.xlabel('시간')
    plt.suptitle(f'{sector}부문 시간대별 전력소비량(MWh) 분포')
    plt.grid()
    plt.xticks(np.arange(24), labels=list(range(1, 25)))
    plt.show()

    # 요일별 전력소비량을 산포도 형태의 그래프로 그림
    sns.pairplot(grp_hour, x_vars=['weekday'], y_vars='전력사용량(kWh)', hue='tm(시간)', height=5, plot_kws={'alpha':0.1, 'linewidth':0})
    plt.ylabel('전력소비량(MWh)')
    plt.suptitle(f'{sector}부문 요일별/시간대별 전력소비량(MWh) 분포(월-금, 토, 일')
    plt.grid()
    plt.xticks(np.arange(7), labels=['월', '화', '수', '목', '금', '토', '일'])
    plt.show()

    # 주/시간별 전력소비량을 산포도 형태의 그래프로 그림
    sns.pairplot(grp_hour, x_vars=['weekofyear'], y_vars='전력사용량(kWh)', hue='tm(시간)', height=5, plot_kws={'alpha':0.1, 'linewidth':0})
    plt.ylabel('전력소비량(MWh)')
    plt.suptitle(f'{sector}부문 주별/시간대별 전력소비량(MWh) 분포')
    plt.grid()
    plt.show()
In [6]:
basic_graph(df_b, '건물')
In [7]:
df_p = pd.read_pickle('building_pivot.pkl')
df_p
Out[7]:
tm(시간) kemc_oldx_code_tite ente dt(날짜) 0 1 2 3 4 5 6 ... 14 15 16 17 18 19 20 21 22 23
0 IDC(전화국) 1192 2021-01-01 5982.48 5956.56 5949.36 5927.76 5925.60 5929.92 5940.72 ... 6022.80 6026.40 6021.36 6017.04 6009.84 6008.40 6013.44 6040.08 6014.16 5998.32
1 IDC(전화국) 1192 2021-01-02 5995.44 5974.56 5963.04 5954.40 5945.04 5929.92 5924.16 ... 6089.76 6089.04 6068.88 6039.36 5994.72 5994.00 5976.00 5965.20 5970.24 5954.40
2 IDC(전화국) 1192 2021-01-03 5933.52 5921.28 5901.12 5890.32 5878.80 5874.48 5868.72 ... 6029.28 6044.40 6017.04 6012.00 6013.44 5997.60 5992.56 5976.72 5970.96 5954.40
3 IDC(전화국) 1192 2021-01-04 5933.52 5930.64 5901.12 5891.76 5883.84 5968.80 6017.76 ... 6387.12 6403.68 6394.32 6376.32 6226.56 6093.36 6052.32 6060.24 6051.60 6049.44
4 IDC(전화국) 1192 2021-01-05 6027.12 5998.32 5993.28 5973.12 5973.12 6016.32 6092.64 ... 6366.96 6382.80 6384.96 6333.84 6167.52 6122.88 6092.64 6001.20 5970.96 5953.68
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
275570 호텔 58967 2021-12-27 1033.92 905.52 945.12 841.68 866.40 991.44 1079.04 ... 1671.12 1673.04 1638.72 1704.24 1458.72 1256.88 1134.00 1157.04 981.36 910.56
275571 호텔 58967 2021-12-28 905.28 883.92 831.36 802.80 865.44 996.96 1068.96 ... 1473.36 1480.80 1434.72 1689.60 1443.36 1180.32 1142.16 1001.04 990.24 871.68
275572 호텔 58967 2021-12-29 823.92 828.48 749.76 750.96 822.00 837.12 971.76 ... 1456.08 1650.00 1475.52 1539.84 1510.08 1232.16 1205.52 1193.76 1036.08 889.68
275573 호텔 58967 2021-12-30 874.32 893.04 816.24 820.32 938.40 917.76 948.00 ... 1607.76 1667.04 1545.12 1795.44 1703.04 1402.56 1472.16 1406.64 1237.44 1067.52
275574 호텔 58967 2021-12-31 989.52 1034.88 961.68 898.56 890.88 1006.80 1218.96 ... 1577.76 1652.16 1590.72 1747.44 1590.96 1473.12 1345.68 1428.48 1286.16 1171.20

275575 rows × 27 columns

In [10]:
def load_profile(df_pivot, sector):
    # 시간별 전력소비량만 정규화
    df_pivot.iloc[:, 3:27] = df_pivot.iloc[:, 3:27].apply(lambda x : x/x.max(), axis=1)
    df_pivot['weekday'] = df_pivot['dt(날짜)'].dt.dayofweek # 요일 컬럼 추가
    #print(df_pivot.head())

    df_wk = df_pivot[df_pivot['weekday'] <= 4] # 주중
    df_wn = df_pivot[df_pivot['weekday'] > 4] # 주말

    # 전체, 주중, 주말 데이터 도출
    grp_all = df_pivot.groupby('kemc_oldx_code_tite')[list(range(0, 24))].mean() * 100
    grp_wk = df_wk.groupby('kemc_oldx_code_tite')[list(range(0, 24))].mean() * 100
    grp_wn = df_wn.groupby('kemc_oldx_code_tite')[list(range(0, 24))].mean() * 100

    grp_all.T.plot()
    plt.ylabel('소비량(정규화)')
    plt.title(f'{sector}부문 업종별 부하패턴 : 전체')
    plt.legend(loc='best')
    plt.grid(which='both')
    plt.xticks(np.arange(24), labels=list(range(1, 25)))
    plt.show()

    grp_wk.T.plot()
    plt.ylabel('소비량(정규화)')
    plt.title(f'{sector}부문 업종별 부하패턴 : 주중')
    plt.legend(loc='best')
    plt.grid(which='both')
    plt.xticks(np.arange(24), labels=list(range(1, 25)))
    plt.show()

    grp_wn.T.plot()
    plt.ylabel('소비량(정규화)')
    plt.title(f'{sector}부문 업종별 부하패턴 : 주말')
    plt.legend(loc='best')
    plt.grid(which='both')
    plt.xticks(np.arange(24), labels=list(range(1, 25)))
    plt.show()
In [11]:
load_profile(df_p, '건물')
In [12]:
def load_factor(data, sector):
    # 일자별 부하율 계산
    data['LF'] = data.drop(['ente'], axis=1).mean(axis=1) / data.drop(['ente'], axis=1).max(axis=1) * 100

    # 용도별/월별 부하율 계산
    data['month'] = data['dt(날짜)'].dt.month
    pivot_lf = pd.pivot_table(data, index='kemc_oldx_code_tite', columns='month', values='LF', aggfunc=np.mean)
    #print(pivot_lf)
    
    pivot_lf.T.plot()
    plt.ylabel('부하율(%)')
    plt.title(f'{sector}부문 업종별/월별 부하율')
    plt.legend(loc='best')
    plt.grid(which='both')
    plt.show()

    sns.boxplot(x='month', y='LF', data=data)
    plt.ylabel('부하율(%)')
    plt.title(f'{sector}부문 업종별/월별 부하율 4분위')
    plt.grid(which='both')
    plt.show()
In [13]:
load_factor(df_p, '건물')
In [14]:
def detail_type(data):
    #print(data.head())

    for idx in data['kemc_oldx_code_tite'].unique():
        btype = data[data['kemc_oldx_code_tite'] == idx].copy() # 용도별 구분

        btype.iloc[:, 3:27] = btype.iloc[:, 3:27].apply(lambda x : x/x.max(), axis=1) # 정규화

        btype_site = btype.groupby('ente')[list(range(0, 24))].mean() # 용도의 시간별 평균 계산
        btype_site_mean = btype_site.mean()

        btype_site.T.plot(alpha=0.7, linewidth=0.7)
        btype_site_mean.plot(linewidth=3)

        plt.grid()
        plt.legend().remove()
        plt.xlabel('시간')
        plt.ylabel('전력소비량(정규화)')
        plt.title(f'{idx} 개별 사업장 및 평균 부하곡선')
        plt.xticks(np.arange(24), labels=list(range(1, 25)))
        plt.show()
In [15]:
detail_type(df_p)
In [18]:
def peak_hour(data):
    #print(data.head())
    grp_type = data.groupby(['kemc_oldx_code_tite', 'dt(날짜)'])[list(range(0, 24))].sum()
    grp_type = grp_type.reset_index()

    grp_type['peak'] = grp_type[list(range(0, 24))].idxmax(axis=1) # 하루 중 피크인 시간대 도출

    bar_type = grp_type.groupby('kemc_oldx_code_tite')['peak'].value_counts() # 시간대별 피크인 사업장수 도출
    bar_type = bar_type.unstack().fillna(0)
    bar_type.iloc[:, :] = bar_type.iloc[:, :].apply(lambda x: x / x.sum(), axis=1) * 100


    bar_type_stack = bar_type.stack()
    bar_type_stack = bar_type_stack.reset_index()
    bar_type_stack.columns = ['type', 'hour', 'peak']
    bar_type_stack['hour'] = bar_type_stack['hour'] + 1
    sns.barplot(data=bar_type_stack, x='hour', y='peak', hue='type')
    
    plt.grid()
    plt.legend()
    plt.xlabel('시간')
    plt.ylabel('비중(%)')
    plt.title('용도별 피크시간 비중')
    plt.show()
In [19]:
peak_hour(df_p)