2023년 3월 26일 일요일

Pandas 사용법

 위치: D:\2023\TemporalFusionTransformer

# index_col: 원하는 col을 index로 지정하여 불러오기(첫 col을 index로)
data = pd.read_csv('LD2011_2014.txt', index_col=0, sep=';', decimal=',')
# series나 df를 datetime객체로 변환:
#             따라서 여기서는 index이면서, datetime임(2가지 속성)
data.index = pd.to_datetime(data.index)
data.sort_index(inplace=True)
data.head(5)


# resampling후 np.nan값은 0.으로.
data = data.resample('1h').mean().replace(0., np.nan)
earliest_time = data.index.min()
df=data[['MT_002', 'MT_004', 'MT_005', 'MT_006', 'MT_008' ]]

df_list = []
for label in df:
    # (1) index는 MT_002 col추출 시 자동으로 함께 추출(index이므로)
    # (2) index는 datetime이므로 date, time도 추출 가능
    #     ts.index.date(날짜), ts.index.time(시간) 등.
    ts = df[label]

    # ffill(front fill: 앞값으로 채움), bfill(back fill: 뒷값으로 채움)
    start_date = min(ts.fillna(method='ffill').dropna().index)
    end_date = max(ts.fillna(method='bfill').dropna().index)

    # 필요한 data 부분을 slicing하기 위해 activae_range영역을 만듬.
    # True가 되는 부분만 slicing됨. Na, NaN이 아닌 값만 추출됨
    active_range = (ts.index >= start_date) & (ts.index <= end_date)
    ts = ts[active_range].fillna(0.)

    tmp = pd.DataFrame({'power_usage': ts})
    date = tmp.index

    # 전력 사용량은 시간 factor가 중요함
    tmp['hours_from_start'] = (date - earliest_time).seconds / 60 / 60 + (date - earliest_time).days * 24
    tmp['hours_from_start'] = tmp['hours_from_start'].astype('int')
    tmp['days_from_start'] = (date - earliest_time).days
    tmp['date'] = date
    tmp['consumer_id'] = label
    tmp['hour'] = date.hour
    tmp['day'] = date.day
    tmp['day_of_week'] = date.dayofweek
    tmp['month'] = date.month

    #stack all time series vertically
    df_list.append(tmp)

time_df = pd.concat(df_list).reset_index(drop=True)

# match results in the original paper
time_df = time_df[(time_df['days_from_start'] >= 1096)
                & (time_df['days_from_start'] < 1346)].copy()


# building cluster based on kmeans
CLUSTER = {
    0: [19, 20, 21, 49, 50, 51],
    1: [1, 5, 9, 34],
    2: [4, 10, 11, 12, 28, 29, 30, 36, 40, 41, 42, 59, 60],
    3: [2, 3, 6, 7, 8, 13, 14, 15, 16, 17, 18, 22, 23, 24, 25, 26, 27, 31, 32, 33, 35, 37, 38, 39, 43, 44, 45, 46, 47, 48, 52, 53, 54, 55, 56, 57, 58],
}

# assing cluster number to building
for k, nums in CLUSTER.items():
    # df.num.isin(nums): 현재 df.num값이 [19,20,21,...]에 있으면 T, else F.
    # df.loc[~ ~, 'cluster']: 행 index위치에 T, F를 넣으면 T인 경우만 선택됨
    df.loc[df.num.isin(nums), 'cluster'] = k


# FEATURE: `hot` flag when the next day is holiday
# shift(-1): 위로 한칸 밀기. fillna(0): Na, NaN은 0으로.
hot = df.groupby('date').first()['holiday'].shift(-1).fillna(0).astype(int)
#hot = hot.to_frame().reset_index().rename({'holiday': "hot"}, axis=1)
#df = df.merge(hot, on='date', how='left')

# (1) 앞연산으로 동일값이 반복되는 row가 많아 나오면
# (2) first()에 의해 첫번째 row 만 추출
df.groupby('date').first()  


hot = df.groupby('date').first()['holiday'].shift(-1).fillna(0).astype(int)
# to_frame(): series를 df로, reset_index: 맨 앞에 순서 0,1,2,...를 index로 붙여줌
hot = hot.to_frame().reset_index().rename({'holiday': "hot"}, axis=1)


[Reference] 



댓글 없음:

댓글 쓰기