Post

[Pandas 기초] 7. 시계열 데이터 처리

Python Library 중 하나인 Pandas에서 시계열 데이터를 처리하는 방법을 알아보자.

시계열 데이터

  • 행과 행에 시간의 순서(흐름)가 있고
  • 행과 행의 시간 간격이 동일한 데이터 (엄격한 기준임)
  • Time Series = Sequential Data 라고도 부름

날짜 요소 추출

날짜 타입으로 변환

  • 보통, 데이터에서 날짜는 data type이 object로 되어있음
  • 이를 data['Date'] = pd.to_datetime(data['Date'])와 같이 datetime으로 변경해준다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

sales = pd.read_csv("https://raw.githubusercontent.com/DA4BAM/dataset/master/ts_sales_simple.csv")
products = pd.read_csv("https://raw.githubusercontent.com/DA4BAM/dataset/master/ts_product_master.csv")

# 판매액 계산하기
temp = pd.merge(sales, products)
temp['Amt' ] = temp['Qty'] * temp['Price']
temp['Amt'] = (temp['Amt']/1000).round()  # 단위 1000달러

# 집계
data1 = temp.groupby(['Date', 'Category'], as_index = False)['Amt'].sum()
data2 = temp.groupby(['Date'], as_index = False)['Amt'].sum()

data11 = data1.pivot('Date', 'Category', 'Amt').reset_index()
data = pd.merge(data2, data11)
data.head()
DateAmtDrinkFoodGroceryHousehold Goods
02013-01-0120.07.04.06.03.0
12013-01-023938.0604.0549.01663.01122.0
22013-01-032885.0444.0376.01222.0843.0
32013-01-042907.0490.0386.01252.0779.0
42013-01-053831.0704.0505.01560.01062.0
  • 데이터가 위와 같을 때, Date 칼럼을 Datetime으로 변경해보자
1
2
# data 확인
data.info()
1
2
3
4
5
6
7
8
9
10
11
12
13
<class 'pandas.core.frame.DataFrame'>
Int64Index: 31 entries, 0 to 30
Data columns (total 6 columns):
 #   Column           Non-Null Count  Dtype  
---  ------           --------------  -----  
 0   Date             31 non-null     object 
 1   Amt              31 non-null     float64
 2   Drink            31 non-null     float64
 3   Food             31 non-null     float64
 4   Grocery          31 non-null     float64
 5   Household Goods  31 non-null     float64
dtypes: float64(5), object(1)
memory usage: 1.7+ KB
1
2
3
4
5
# datetime으로 변환
data['Date'] = pd.to_datetime(data['Date'])

# 확인
data.info()
1
2
3
4
5
6
7
8
9
10
11
12
13
<class 'pandas.core.frame.DataFrame'>
Int64Index: 31 entries, 0 to 30
Data columns (total 6 columns):
 #   Column           Non-Null Count  Dtype         
---  ------           --------------  -----         
 0   Date             31 non-null     datetime64[ns]
 1   Amt              31 non-null     float64       
 2   Drink            31 non-null     float64       
 3   Food             31 non-null     float64       
 4   Grocery          31 non-null     float64       
 5   Household Goods  31 non-null     float64       
dtypes: datetime64[ns](1), float64(5)
memory usage: 1.7 KB
  • format = ‘’
    • pd.to_datetime(date, format = '%d/%m/%Y')
    • format = ‘%d/%m/%Y’ 입력되는 날짜가 이런 형태야~~ 라고 알려주는 옵션
1
2
3
date = pd.Series(['03-01-2023', '03-02-2023', '03-03-2023'])
date = pd.to_datetime(date)
date
1
2
3
4
0   2023-03-01
1   2023-03-02
2   2023-03-03
dtype: datetime64[ns]
1
2
3
date = pd.Series(['03-01-2023', '03-02-2023', '03-03-2023'])
date = pd.to_datetime(date, format = '%d-%m-%Y') #입력받은 날짜 데이터 형식이 '%d-%m-%Y'!
date
1
2
3
4
0   2023-01-03
1   2023-02-03
2   2023-03-03
dtype: datetime64[ns]

날짜 요소 추출

  • 날짜 타입의 변수로부터 날짜의 요소를 뽑아낼 수 있음
  • data['yaer'] = data['date'].dt.year 와 같이 뽑아내고 할당할 수 있음
  • 사진과 같이 다양한 method가 있음

dt_method

1
2
3
# datetime 에서 날짜 요소 추출 해보기
data['weekday'] = data['Date'].dt.weekday
data.head(3)
DateAmtDrinkFoodGroceryHousehold Goodsweekday
02013-01-0120.07.04.06.03.01
12013-01-023938.0604.0549.01663.01122.02
22013-01-032885.0444.0376.01222.0843.03

시간에 따른 흐름 추출하기 : Time Lag

  • 시계열 데이터에 사용
  • shift, rolling, diff 가 있다.

.shift()

  • 시계열 데이터에서 시간의 흐름 전후로 정보를 이동시킬 때 사용
  • temp['Amt_lag'] = temp['Amt'].shift(periods=n) 과 같이 사용
  • n행 shift 한다는 의미임. periods 생략 가능. 기본값은 1
1
2
3
4
5
6
7
8
9
10
11
12
temp = data.loc[:,['Date','Amt']]

# 전날 매출액 열을 추가합시다.
temp['Amt_lag'] = temp['Amt'].shift() #default = 1

# 전전날 매출액 열을 추가.
temp['Amt_lag2'] = temp['Amt'].shift(2) # 2행 shift

# 다음날 매출액 열을 추가합시다.
temp['Amt_lag_1'] = temp['Amt'].shift(-1)

temp.head()
DateAmtAmt_lagAmt_lag2Amt_lag_1
02013-01-0120.0NaNNaN3938.0
12013-01-023938.020.0NaN2885.0
22013-01-032885.03938.020.02907.0
32013-01-042907.02885.03938.03831.0
42013-01-053831.02907.02885.04066.0

.rolling().mean()

  • 시간의 흐름에 따라 일정 기간 동안 평균을 이동하면서 구하기
  • .rolling(n):
    • n 기본값은 1
    • min_periods : 최소 데이터 수
    • min_periods 설정이 없으면, n일까지는 이전 데이터가 없기 때문에 NaN이 뜨지만, 설정하게되면 설정한 값부터 값을 내줌
  • .rolling().mean()은 이동평균값
1
2
3
4
# 7일 이동평균 매출액을 구해 봅시다.
temp['Amt_MA7_1'] = temp['Amt'].rolling(7).mean()
temp['Amt_MA7_2'] = temp['Amt'].rolling(7, min_periods = 1).mean()
temp.head(10)
DateAmtAmt_lagAmt_lag2Amt_lag_1Amt_MA7_1Amt_MA7_2
02013-01-0120.0NaNNaN3938.0NaN20.000000
12013-01-023938.020.0NaN2885.0NaN1979.000000
22013-01-032885.03938.020.02907.0NaN2281.000000
32013-01-042907.02885.03938.03831.0NaN2437.500000
42013-01-053831.02907.02885.04066.0NaN2716.200000
52013-01-064066.03831.02907.02700.0NaN2941.166667
62013-01-072700.04066.03831.02533.02906.7142862906.714286
72013-01-082533.02700.04066.02462.03265.7142863265.714286
82013-01-092462.02533.02700.02110.03054.8571433054.857143
92013-01-102110.02462.02533.02405.02944.1428572944.142857

.diff()

  • 특정 시점 데이터, 이전시점 데이터와의 차이 구하기
  • temp['Amt_D1'] = temp['Amt'].diff(n)과 같이 사용
  • n행 전과 차이를 구한다는 의미
1
2
3
temp['Amt_D1'] = temp['Amt'].diff()
temp['Amt_D2'] = temp['Amt'].diff(2)
temp.head(5)
DateAmtAmt_lagAmt_lag2Amt_lag_1Amt_MA7_1Amt_MA7_2Amt_D1Amt_D2
02013-01-0120.0NaNNaN3938.0NaN20.0NaNNaN
12013-01-023938.020.0NaN2885.0NaN1979.03918.0NaN
22013-01-032885.03938.020.02907.0NaN2281.0-1053.02865.0
32013-01-042907.02885.03938.03831.0NaN2437.522.0-1031.0
42013-01-053831.02907.02885.04066.0NaN2716.2924.0946.0
This post is licensed under CC BY 4.0 by the author.

[Pandas 기초] 6. DataFrame 결합

가변수화, One-Hot Encoding(원핫인코딩) 방법