본문 바로가기
개발일지/Python

pandas 판다스 기초 25 datetime 데이터 핸들링의 모든것

by 개발에정착하고싶다 2022. 8. 24.
320x100

이번 섹션은 상당히 단조롭다.

대체로 datetime을 다루는 섹션인데

datetime이라는 주제 하나로 엄청나게 다양한 사용범위를 보여준다.


# Time Series Basics

## Importing Time Series Data from csv-Files

import pandas as pd

temp = pd.read_csv('temp.csv')
temp.head()

'''
    datetime	LA	NY
0	2013-01-01 00:00:00	11.7	-1.1
1	2013-01-01 01:00:00	10.7	-1.7
2	2013-01-01 02:00:00	9.9	-2.0
3	2013-01-01 03:00:00	9.3	-2.1
4	2013-01-01 04:00:00	8.8	-2.3
'''
temp.info()

'''
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 35064 entries, 0 to 35063
Data columns (total 3 columns):
 #   Column    Non-Null Count  Dtype  
---  ------    --------------  -----  
 0   datetime  35064 non-null  object 
 1   LA        35062 non-null  float64
 2   NY        35064 non-null  float64
dtypes: float64(2), object(1)
memory usage: 821.9+ KB
'''

# datetime의 dtype이 object이다.
# 이것을 datetime으로 바꿔주기 위해서 재 임포트 해준다.
# info로 확인 결과.
# dtype변경을 위한 재 임포트

temp = pd.read_csv('temp.csv', parse_dates=['datetime'])
temp.head()

'''
datetime	LA	NY
0	2013-01-01 00:00:00	11.7	-1.1
1	2013-01-01 01:00:00	10.7	-1.7
2	2013-01-01 02:00:00	9.9	-2.0
3	2013-01-01 03:00:00	9.3	-2.1
4	2013-01-01 04:00:00	8.8	-2.3
'''
temp.info()

'''
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 35064 entries, 0 to 35063
Data columns (total 3 columns):
 #   Column    Non-Null Count  Dtype         
---  ------    --------------  -----         
 0   datetime  35064 non-null  datetime64[ns]
 1   LA        35062 non-null  float64       
 2   NY        35064 non-null  float64       
dtypes: datetime64[ns](1), float64(2)
memory usage: 821.9 KB
'''

# ns는 nano seconds를 의미한다.
temp.iloc[0,0]

# Timestamp('2013-01-01 00:00:00')
# datetime으로 오버라이딩 하기 전에는 Timestamp가 나오지 않았지만,
# 현재는 나온다.
type(temp.iloc[0,0])

# pandas._libs.tslibs.timestamps.Timestamp
# 다시 임포트를 한다.
# 근데 왜자꾸 인덱스로 지정을 해주는 걸까?

# index_col은 인덱스 지정(index 지정)
temp = pd.read_csv('temp.csv', parse_dates=['datetime'], index_col = 'datetime')
temp.info()

'''
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 35064 entries, 2013-01-01 00:00:00 to 2016-12-31 23:00:00
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   LA      35062 non-null  float64
 1   NY      35064 non-null  float64
dtypes: float64(2)
memory usage: 821.8 KB
'''

# 결과적으로 봤을때, 인덱스로 지정해주면, 기존의 3개의 컬럼에서 2개로 줄어드는 효과는 있다.
temp.index

'''
DatetimeIndex(['2013-01-01 00:00:00', '2013-01-01 01:00:00',
               '2013-01-01 02:00:00', '2013-01-01 03:00:00',
               '2013-01-01 04:00:00', '2013-01-01 05:00:00',
               '2013-01-01 06:00:00', '2013-01-01 07:00:00',
               '2013-01-01 08:00:00', '2013-01-01 09:00:00',
               ...
               '2016-12-31 14:00:00', '2016-12-31 15:00:00',
               '2016-12-31 16:00:00', '2016-12-31 17:00:00',
               '2016-12-31 18:00:00', '2016-12-31 19:00:00',
               '2016-12-31 20:00:00', '2016-12-31 21:00:00',
               '2016-12-31 22:00:00', '2016-12-31 23:00:00'],
              dtype='datetime64[ns]', name='datetime', length=35064, freq=None)
'''

# 재미있는 점은 datetime으로 오버라이딩 하기 전에는
# temp.index라고 했을때 딸랑 한개의 date값만 나왔었다.
# 물론 그 때의 데이터 타입은 object였다.


## Converting strings to datetime objects with pd.to_datetime()

import pandas as pd

temp = pd.read_csv('temp.csv')

temp.head()

'''

datetime	LA	NY
0	2013-01-01 00:00:00	11.7	-1.1
1	2013-01-01 01:00:00	10.7	-1.7
2	2013-01-01 02:00:00	9.9	-2.0
3	2013-01-01 03:00:00	9.3	-2.1
4	2013-01-01 04:00:00	8.8	-2.3
'''
temp.info()

'''
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 35064 entries, 0 to 35063
Data columns (total 3 columns):
 #   Column    Non-Null Count  Dtype  
---  ------    --------------  -----  
 0   datetime  35064 non-null  object 
 1   LA        35062 non-null  float64
 2   NY        35064 non-null  float64
dtypes: float64(2), object(1)
memory usage: 821.9+ KB
'''
temp.datetime

'''
0        2013-01-01 00:00:00
1        2013-01-01 01:00:00
2        2013-01-01 02:00:00
3        2013-01-01 03:00:00
4        2013-01-01 04:00:00
                ...         
35059    2016-12-31 19:00:00
35060    2016-12-31 20:00:00
35061    2016-12-31 21:00:00
35062    2016-12-31 22:00:00
35063    2016-12-31 23:00:00
Name: datetime, Length: 35064, dtype: object
'''
pd.to_datetime(temp.datetime)

'''
0       2013-01-01 00:00:00
1       2013-01-01 01:00:00
2       2013-01-01 02:00:00
3       2013-01-01 03:00:00
4       2013-01-01 04:00:00
                ...        
35059   2016-12-31 19:00:00
35060   2016-12-31 20:00:00
35061   2016-12-31 21:00:00
35062   2016-12-31 22:00:00
35063   2016-12-31 23:00:00
Name: datetime, Length: 35064, dtype: datetime64[ns]
'''

# pd.to_datetime이 ()안에 들어오는 컬럼을 datetime으로 바꿔준다는 명령이다.
temp.set_index(pd.to_datetime(temp.datetime)).drop('datetime', axis = 1)

'''
	LA	NY
datetime		
2013-01-01 00:00:00	11.7	-1.1
2013-01-01 01:00:00	10.7	-1.7
2013-01-01 02:00:00	9.9	-2.0
2013-01-01 03:00:00	9.3	-2.1
2013-01-01 04:00:00	8.8	-2.3
...	...	...
2016-12-31 19:00:00	13.5	4.6
2016-12-31 20:00:00	13.2	5.7
2016-12-31 21:00:00	12.8	5.8
2016-12-31 22:00:00	12.3	5.7
2016-12-31 23:00:00	11.9	5.5
35064 rows × 2 columns
'''
temp.head()

'''
datetime	LA	NY
0	2013-01-01 00:00:00	11.7	-1.1
1	2013-01-01 01:00:00	10.7	-1.7
2	2013-01-01 02:00:00	9.9	-2.0
3	2013-01-01 03:00:00	9.3	-2.1
4	2013-01-01 04:00:00	8.8	-2.3
'''
temp.index

# RangeIndex(start=0, stop=35064, step=1)
pd.to_datetime('2015-05-20')

# Timestamp('2015-05-20 00:00:00')


## Initial Analysis / Visual Inspection of Time Series

temp.head()

'''

datetime	LA	NY
0	2013-01-01 00:00:00	11.7	-1.1
1	2013-01-01 01:00:00	10.7	-1.7
2	2013-01-01 02:00:00	9.9	-2.0
3	2013-01-01 03:00:00	9.3	-2.1
4	2013-01-01 04:00:00	8.8	-2.3
'''
temp.info()

'''
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 35064 entries, 0 to 35063
Data columns (total 3 columns):
 #   Column    Non-Null Count  Dtype  
---  ------    --------------  -----  
 0   datetime  35064 non-null  object 
 1   LA        35062 non-null  float64
 2   NY        35064 non-null  float64
dtypes: float64(2), object(1)
memory usage: 821.9+ KB
'''
temp.describe()

'''
LA	NY
count	35062.000000	35064.000000
mean	17.486016	12.068269
std	6.640666	10.466832
min	-6.600000	-22.400000
25%	12.900000	3.900000
50%	17.200000	12.500000
75%	21.900000	20.600000
max	42.300000	37.100000
'''
temp.LA.value_counts()

'''
 16.2    238
 16.7    237
 15.2    234
 18.2    231
 16.6    228
        ... 
-5.9       1
-6.5       1
-6.6       1
-2.2       1
-3.3       1
Name: LA, Length: 442, dtype: int64
'''
import matplotlib.pyplot as plt

temp.plot(figsize = (14,10))
plt.show()

# plots 를 분할
temp.plot(figsize = (14,10), subplots = True)
plt.show()

# layout은 1개의 행을 가지고 2개의 컬럼을 두고 비교

temp.plot(figsize = (14,10), subplots = True, layout = (1, 2))
plt.show()

# 때문에 NY은 -20 부터 시작하고, LA는 0부터 시작한다.

# sharey는 y축의 공유 여부 즉, 두개의 y축은 같은 값을 가지게 된다.

temp.plot(figsize = (14,10), subplots = True, layout =(1,2), sharey = True)
plt.show()



## Indexing and Slicing Time Series

# 다시 기억해 두자.
# index_col은 read_csv를 임포트 하는 순간에 index_col에 지정된 값으로 인덱스 설정을 해준다.
# 따라서, 해당 컬럼은 더이상 컬럼이 아니고 인덱스화가 되는 개념이라고 보면 된다.

import pandas as pd

temp = pd.read_csv('temp.csv', parse_dates = ['datetime'], index_col = 'datetime')
temp.head()

'''

LA	NY
datetime		
2013-01-01 00:00:00	11.7	-1.1
2013-01-01 01:00:00	10.7	-1.7
2013-01-01 02:00:00	9.9	-2.0
2013-01-01 03:00:00	9.3	-2.1
2013-01-01 04:00:00	8.8	-2.3
'''
temp.info()

'''
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 35064 entries, 2013-01-01 00:00:00 to 2016-12-31 23:00:00
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   LA      35062 non-null  float64
 1   NY      35064 non-null  float64
dtypes: float64(2)
memory usage: 821.8 KB
'''
temp.loc['2013-01-01 01:00:00']

'''
LA    10.7
NY    -1.7
Name: 2013-01-01 01:00:00, dtype: float64
'''
# 2015년의 모든 타임스탬프 소환

temp.loc['2015']

'''
	LA	NY
datetime		
2015-01-01 00:00:00	3.8	-5.1
2015-01-01 01:00:00	4.4	-5.1
2015-01-01 02:00:00	3.2	-6.0
2015-01-01 03:00:00	1.2	-6.0
2015-01-01 04:00:00	0.2	-6.0
...	...	...
2015-12-31 19:00:00	16.0	8.1
2015-12-31 20:00:00	16.0	8.1
2015-12-31 21:00:00	16.4	7.9
2015-12-31 22:00:00	16.6	7.2
2015-12-31 23:00:00	16.8	6.2
8760 rows × 2 columns
'''
temp.loc['2015-05']

'''
	LA	NY
datetime		
2015-05-01 00:00:00	25.5	13.9
2015-05-01 01:00:00	25.7	13.9
2015-05-01 02:00:00	23.8	10.5
2015-05-01 03:00:00	22.0	10.2
2015-05-01 04:00:00	20.1	8.6
...	...	...
2015-05-31 19:00:00	25.4	25.5
2015-05-31 20:00:00	26.0	23.9
2015-05-31 21:00:00	24.9	22.5
2015-05-31 22:00:00	26.0	21.3
2015-05-31 23:00:00	25.5	19.9
744 rows × 2 columns
'''
temp.loc['2015-05-20'].shape

# (24, 2)
temp.loc['2015-01-01':'2015-12-31']

'''
	LA	NY
datetime		
2015-01-01 00:00:00	3.8	-5.1
2015-01-01 01:00:00	4.4	-5.1
2015-01-01 02:00:00	3.2	-6.0
2015-01-01 03:00:00	1.2	-6.0
2015-01-01 04:00:00	0.2	-6.0
...	...	...
2015-12-31 19:00:00	16.0	8.1
2015-12-31 20:00:00	16.0	8.1
2015-12-31 21:00:00	16.4	7.9
2015-12-31 22:00:00	16.6	7.2
2015-12-31 23:00:00	16.8	6.2
8760 rows × 2 columns
'''
temp.loc['2015-01-01': "2015-12-31"].equals(temp.loc['2015'])

# True
# 둘다 2015년의 데이터를 의미하는 코드다.
temp.loc[:'2015-05-20']

'''

LA	NY
datetime		
2013-01-01 00:00:00	11.7	-1.1
2013-01-01 01:00:00	10.7	-1.7
2013-01-01 02:00:00	9.9	-2.0
2013-01-01 03:00:00	9.3	-2.1
2013-01-01 04:00:00	8.8	-2.3
...	...	...
2015-05-20 19:00:00	17.7	18.1
2015-05-20 20:00:00	18.4	17.8
2015-05-20 21:00:00	18.0	17.8
2015-05-20 22:00:00	19.1	14.2
2015-05-20 23:00:00	19.1	14.2
20880 rows × 2 columns
'''
temp.loc[['2015-05-20 10:00:00', '2015-05-20 12:00:00']]

'''

                    LA	NY
datetime		
2015-05-20 10:00:00	7.8	13.3
2015-05-20 12:00:00	9.7	13.6
'''
two_timestamp = pd.to_datetime(['2015-05-20 10:00:00', '2015-05-20 12:00:00'])
two_timestamp

# DatetimeIndex(['2015-05-20 10:00:00', '2015-05-20 12:00:00'], dtype='datetime64[ns]', freq=None)
temp.loc[two_timestamp]

'''

                    LA	NY
2015-05-20 10:00:00	7.8	13.3
2015-05-20 12:00:00	9.7	13.6
'''


## Creating a customized DatetimeIndex with pd.date_range()

import pandas as pd

pd.to_datetime(['2015-05-20', 'Feb 20 2015'])

# DatetimeIndex(['2015-05-20', '2015-02-20'], dtype='datetime64[ns]', freq=None)
# to_datetime 메소드에 내가 원하는 날자가 31개라면 해당 하는 문자열을 모두 쓰는 것은
# 매우 비 효율 적이다.
# 따라서 slice와 같은 기능을 써준다.

pd.date_range(start = '2015-07-01', end = '2015-07-31')

'''
DatetimeIndex(['2015-07-01', '2015-07-02', '2015-07-03', '2015-07-04',
               '2015-07-05', '2015-07-06', '2015-07-07', '2015-07-08',
               '2015-07-09', '2015-07-10', '2015-07-11', '2015-07-12',
               '2015-07-13', '2015-07-14', '2015-07-15', '2015-07-16',
               '2015-07-17', '2015-07-18', '2015-07-19', '2015-07-20',
               '2015-07-21', '2015-07-22', '2015-07-23', '2015-07-24',
               '2015-07-25', '2015-07-26', '2015-07-27', '2015-07-28',
               '2015-07-29', '2015-07-30', '2015-07-31'],
              dtype='datetime64[ns]', freq='D')
'''
# 중요 freq는 주기를 의미한다.
# D는 day를 의미

pd.date_range(start = '2015-07-01', periods = 31, freq = 'D')

'''
DatetimeIndex(['2015-07-01', '2015-07-02', '2015-07-03', '2015-07-04',
               '2015-07-05', '2015-07-06', '2015-07-07', '2015-07-08',
               '2015-07-09', '2015-07-10', '2015-07-11', '2015-07-12',
               '2015-07-13', '2015-07-14', '2015-07-15', '2015-07-16',
               '2015-07-17', '2015-07-18', '2015-07-19', '2015-07-20',
               '2015-07-21', '2015-07-22', '2015-07-23', '2015-07-24',
               '2015-07-25', '2015-07-26', '2015-07-27', '2015-07-28',
               '2015-07-29', '2015-07-30', '2015-07-31'],
              dtype='datetime64[ns]', freq='D')
'''
pd.date_range(start = '2015-07-31', periods = 31, freq = 'D')

'''
DatetimeIndex(['2015-07-31', '2015-08-01', '2015-08-02', '2015-08-03',
               '2015-08-04', '2015-08-05', '2015-08-06', '2015-08-07',
               '2015-08-08', '2015-08-09', '2015-08-10', '2015-08-11',
               '2015-08-12', '2015-08-13', '2015-08-14', '2015-08-15',
               '2015-08-16', '2015-08-17', '2015-08-18', '2015-08-19',
               '2015-08-20', '2015-08-21', '2015-08-22', '2015-08-23',
               '2015-08-24', '2015-08-25', '2015-08-26', '2015-08-27',
               '2015-08-28', '2015-08-29', '2015-08-30'],
              dtype='datetime64[ns]', freq='D')
'''
pd.date_range(end = '2015-07-31', periods = 31, freq = 'D')

'''
DatetimeIndex(['2015-07-01', '2015-07-02', '2015-07-03', '2015-07-04',
               '2015-07-05', '2015-07-06', '2015-07-07', '2015-07-08',
               '2015-07-09', '2015-07-10', '2015-07-11', '2015-07-12',
               '2015-07-13', '2015-07-14', '2015-07-15', '2015-07-16',
               '2015-07-17', '2015-07-18', '2015-07-19', '2015-07-20',
               '2015-07-21', '2015-07-22', '2015-07-23', '2015-07-24',
               '2015-07-25', '2015-07-26', '2015-07-27', '2015-07-28',
               '2015-07-29', '2015-07-30', '2015-07-31'],
              dtype='datetime64[ns]', freq='D')
'''
# B는 Business day의 의미로써
# 영업일 즉, 공휴일, 주말을 제외한 평일을 의미한다고 볼 수 있다.
pd.date_range(start = '2015-07-01', end = '2015-07-31', freq = 'B')

'''
DatetimeIndex(['2015-07-01', '2015-07-02', '2015-07-03', '2015-07-06',
               '2015-07-07', '2015-07-08', '2015-07-09', '2015-07-10',
               '2015-07-13', '2015-07-14', '2015-07-15', '2015-07-16',
               '2015-07-17', '2015-07-20', '2015-07-21', '2015-07-22',
               '2015-07-23', '2015-07-24', '2015-07-27', '2015-07-28',
               '2015-07-29', '2015-07-30', '2015-07-31'],
              dtype='datetime64[ns]', freq='B')
'''
# H는 hour 즉, 시간을 단위로 한다.
# periods는 얼마나 많은 index를 추출할거냐. 라고 보면 되겠다.

pd.date_range(start = '2015/07/31', periods = 10, freq = 'H')

'''
DatetimeIndex(['2015-07-31 00:00:00', '2015-07-31 01:00:00',
               '2015-07-31 02:00:00', '2015-07-31 03:00:00',
               '2015-07-31 04:00:00', '2015-07-31 05:00:00',
               '2015-07-31 06:00:00', '2015-07-31 07:00:00',
               '2015-07-31 08:00:00', '2015-07-31 09:00:00'],
              dtype='datetime64[ns]', freq='H')
'''
# freq를 w 로 하면 week day라고 해서, weekday의 시작으로 설정된 날자를 리턴한다.
# 기본 설정은 sunday, 즉 일요일로 되어있다.

pd.date_range(start = '2015-07-01', periods = 6, freq = 'W')

'''
DatetimeIndex(['2015-07-05', '2015-07-12', '2015-07-19', '2015-07-26',
               '2015-08-02', '2015-08-09'],
              dtype='datetime64[ns]', freq='W-SUN')
'''
# weekday의 설정일을 wendsday로 설정

pd.date_range(start = '2015-07-01', periods = 6, freq = 'W-Wed')

'''
DatetimeIndex(['2015-07-01', '2015-07-08', '2015-07-15', '2015-07-22',
               '2015-07-29', '2015-08-05'],
              dtype='datetime64[ns]', freq='W-WED')
'''
# freq를 M으로 할 경우
# 각 월의 말일로 리턴이 된다.

pd.date_range(start = '2015-07-14', periods = 6, freq = 'M')

'''
DatetimeIndex(['2015-07-31', '2015-08-31', '2015-09-30', '2015-10-31',
               '2015-11-30', '2015-12-31'],
              dtype='datetime64[ns]', freq='M')
'''
# freq를 MS로 둔 의미는
# Month start 즉, 월의 시작을 의미한다.

pd.date_range(start = '2015-07-14', periods = 6, freq = 'MS')
# 시작날을 기준으로 한달씩
# 즉, 월의 말일이나, 월의 시작일로 표기되는 것이 아니다.

pd.date_range(start = '2015-07-14', periods = 6, freq = pd.DateOffset(months = 1))

'''
DatetimeIndex(['2015-07-14', '2015-08-14', '2015-09-14', '2015-10-14',
               '2015-11-14', '2015-12-14'],
              dtype='datetime64[ns]', freq='<DateOffset: months=1>')
'''
# freq를 Q로 설정하는것은
# quarter 로써 1/4를 의미한다.
# 그리고 각 3개월의 말일을 리턴한다.

pd.date_range(start = '2015-07-14', periods = 6, freq = 'Q')

'''
DatetimeIndex(['2015-09-30', '2015-12-31', '2016-03-31', '2016-06-30',
               '2016-09-30', '2016-12-31'],
              dtype='datetime64[ns]', freq='Q-DEC')
'''
# 난 SQ로도 될줄알았는데, 그러면 에러가 나더라.
# QS는 분기별로 리턴하되, 해당 분기가 속한 월의 시작일을 리턴

pd.date_range(start = '2015-07-14', periods = 6, freq = 'QS')

'''
DatetimeIndex(['2015-10-01', '2016-01-01', '2016-04-01', '2016-07-01',
               '2016-10-01', '2017-01-01'],
              dtype='datetime64[ns]', freq='QS-JAN')
'''
# QS-MAY는 may로 부터 시작되는 분기를 의미한다.
# 그런데 예제에서는 7월부터 시작되기때문에 5월의 다음이 8월이고 8월이 7월보단 다음차례니깐
# 8월부터 시작해서 3개월씩 리턴된다.


pd.date_range(start = '2015-07-14', periods = 6, freq = 'QS-May')

'''
DatetimeIndex(['2015-08-01', '2015-11-01', '2016-02-01', '2016-05-01',
               '2016-08-01', '2016-11-01'],
              dtype='datetime64[ns]', freq='QS-MAY')
'''
# A는 결과적으로 봤을때 1년마다 각 연의 마지막 날을 리턴해주는 기능 같다.
# A는 annual의 약자다. (연간)
# A대신에 Y를 써줘도 결과값은 같다.

pd.date_range(start = '2015-07-14', periods = 6, freq = 'A')

'''
DatetimeIndex(['2015-12-31', '2016-12-31', '2017-12-31', '2018-12-31',
               '2019-12-31', '2020-12-31'],
              dtype='datetime64[ns]', freq='A-DEC')
'''
# 매년 7월의 시작을 리턴

pd.date_range(start = '2015-07-14', periods = 6, freq = 'AS-JUL')

'''
DatetimeIndex(['2016-07-01', '2017-07-01', '2018-07-01', '2019-07-01',
               '2020-07-01', '2021-07-01'],
              dtype='datetime64[ns]', freq='AS-JUL')
'''
# 다시한번 특정 지정일을 기준으로 1년마다 출력해주기

pd.date_range(end = '2018-11-24', periods = 10, freq = pd.DateOffset(years =1))

'''
DatetimeIndex(['2009-11-24', '2010-11-24', '2011-11-24', '2012-11-24',
               '2013-11-24', '2014-11-24', '2015-11-24', '2016-11-24',
               '2017-11-24', '2018-11-24'],
              dtype='datetime64[ns]', freq='<DateOffset: years=1>')
'''
# 3일 간격

pd.date_range(start = '2015-07-01', periods = 10, freq = '3D')

'''
DatetimeIndex(['2015-07-01', '2015-07-04', '2015-07-07', '2015-07-10',
               '2015-07-13', '2015-07-16', '2015-07-19', '2015-07-22',
               '2015-07-25', '2015-07-28'],
              dtype='datetime64[ns]', freq='3D')
'''


## Downsampling Time Series with resample() (Part 1)

import pandas as pd
import matplotlib.pyplot as plt
plt.style.use('seaborn')

temp = pd.read_csv('temp.csv', parse_dates = ['datetime'], index_col = 'datetime')

'''
	LA	NY
datetime		
2013-01-01 00:00:00	11.7	-1.1
2013-01-01 01:00:00	10.7	-1.7
2013-01-01 02:00:00	9.9	-2.0
2013-01-01 03:00:00	9.3	-2.1
2013-01-01 04:00:00	8.8	-2.3
...	...	...
2016-12-31 19:00:00	13.5	4.6
2016-12-31 20:00:00	13.2	5.7
2016-12-31 21:00:00	12.8	5.8
2016-12-31 22:00:00	12.3	5.7
2016-12-31 23:00:00	11.9	5.5
35064 rows × 2 columns
'''
temp.info()

'''
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 35064 entries, 2013-01-01 00:00:00 to 2016-12-31 23:00:00
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   LA      35062 non-null  float64
 1   NY      35064 non-null  float64
dtypes: float64(2)
memory usage: 821.8 KB
'''
# resample 메소드는 시계열의 주기를 바꾸는 것이다.
# resample은 group by와 유사하다고 한다.
# timestamp를 그룹화 해주는 것이다.

temp.resample('D')

# <pandas.core.resample.DatetimeIndexResampler object at 0x7f9950a9ccd0>
temp.resample('2H').first()

'''
	LA	NY
datetime		
2013-01-01 00:00:00	11.7	-1.1
2013-01-01 02:00:00	9.9	-2.0
2013-01-01 04:00:00	8.8	-2.3
2013-01-01 06:00:00	6.9	-3.2
2013-01-01 08:00:00	6.7	-3.0
...	...	...
2016-12-31 14:00:00	12.7	-1.3
2016-12-31 16:00:00	12.6	1.1
2016-12-31 18:00:00	13.2	3.4
2016-12-31 20:00:00	13.2	5.7
2016-12-31 22:00:00	12.3	5.7
17532 rows × 2 columns
'''
# 이것을 리스트화로 묶을 수도 있다.
# 다운샘플링
list(temp.resample('D'))

# 너무 많아서 이건 적는 것을 생략하겠다.
# 1시간 간격으로, 하루 단위로 그룹화가 되는 기능같다.
temp.resample('D').first()
'''
	LA	NY
datetime		
2013-01-01	11.7	-1.1
2013-01-02	13.2	2.6
2013-01-03	15.1	0.3
2013-01-04	16.3	-1.2
2013-01-05	18.1	-1.2
...	...	...
2016-12-27	15.1	4.1
2016-12-28	19.9	11.2
2016-12-29	23.3	2.1
2016-12-30	25.5	3.0
2016-12-31	15.7	0.8
1461 rows × 2 columns
'''

# 시작을 기준으로 그날그날의 시작가를 알려주는 것같다.
temp.resample('D').last()

'''
	LA	NY
datetime		
2013-01-01	14.0	2.7
2013-01-02	15.1	1.2
2013-01-03	16.6	-1.5
2013-01-04	20.0	-1.2
2013-01-05	17.8	2.0
...	...	...
2016-12-27	20.1	12.9
2016-12-28	24.3	2.6
2016-12-29	25.6	4.2
2016-12-30	15.9	1.2
2016-12-31	11.9	5.5
1461 rows × 2 columns

1

'''
# 종료를 기준으로 그날그날의 종가를 표시해주는 것 같다.
# 물론 정확히는 종가가 아니라 날씨지만 말이다.
temp.resample('D').mean()

'''
	LA	NY
datetime		
2013-01-01	8.858333	-0.404167
2013-01-02	9.283333	3.208333
2013-01-03	10.304167	-2.425000
2013-01-04	11.512500	-2.070833
2013-01-05	11.083333	0.816667
...	...	...
2016-12-27	12.154167	10.579167
2016-12-28	14.433333	4.016667
2016-12-29	16.045833	1.312500
2016-12-30	15.933333	2.204167
2016-12-31	13.275000	1.204167
1461 rows × 2 columns
'''
temp.resample('D').median()

'''

LA	NY
datetime		
2013-01-01	8.75	-1.45
2013-01-02	8.15	3.50
2013-01-03	10.20	-2.35
2013-01-04	9.80	-2.25
2013-01-05	11.30	0.65
...	...	...
2016-12-27	11.35	11.85
2016-12-28	12.60	3.50
2016-12-29	14.40	0.75
2016-12-30	15.30	2.15
2016-12-31	13.20	0.70
1461 rows × 2 columns
'''
temp.resample('D').sum()

'''
LA	NY
datetime		
2013-01-01	212.6	-9.7
2013-01-02	222.8	77.0
2013-01-03	247.3	-58.2
2013-01-04	276.3	-49.7
2013-01-05	266.0	19.6
...	...	...
2016-12-27	291.7	253.9
2016-12-28	346.4	96.4
2016-12-29	385.1	31.5
2016-12-30	382.4	52.9
2016-12-31	318.6	28.9
1461 rows × 2 columns
'''

# 사실 기온을 구할때 sum은 의미가 없다.
# 절대값 기준이면 또 어떤 의미를 찾아낼 수는 있겠어도
# - + 가 공존할 수 있기 때문이다.
temp.resample('2H').first()

'''
	LA	NY
datetime		
2013-01-01 00:00:00	11.7	-1.1
2013-01-01 02:00:00	9.9	-2.0
2013-01-01 04:00:00	8.8	-2.3
2013-01-01 06:00:00	6.9	-3.2
2013-01-01 08:00:00	6.7	-3.0
...	...	...
2016-12-31 14:00:00	12.7	-1.3
2016-12-31 16:00:00	12.6	1.1
2016-12-31 18:00:00	13.2	3.4
2016-12-31 20:00:00	13.2	5.7
2016-12-31 22:00:00	12.3	5.7
17532 rows × 2 columns
'''
temp.resample('M', kind = 'period').mean()
temp_m = temp.resample('M', kind = 'period').mean()

temp_m

'''
LA	NY
datetime		
2013-01	11.596237	1.129570
2013-02	12.587202	0.617857
2013-03	15.069946	3.719220
2013-04	16.487361	10.699306
2013-05	19.005780	15.824328
2013-06	19.905417	22.225694
...
'''
temp_m.info()

'''
<class 'pandas.core.frame.DataFrame'>
PeriodIndex: 48 entries, 2013-01 to 2016-12
Freq: M
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   LA      48 non-null     float64
 1   NY      48 non-null     float64
dtypes: float64(2)
memory usage: 1.1 KB
'''
temp_m.index[0]
import matplotlib.pyplot as plt

temp_m.plot(figsize = (14,10), fontsize = 15)
plt.show()

temp.plot(figsize = (14,10), fontsize = 15)
plt.show()



## The periodIndex Object

import pandas as pd

temp = pd.read_csv('temp.csv', parse_dates = ['datetime'], index_col = 'datetime')
temp.head()

'''
	LA	NY
datetime		
2013-01-01 00:00:00	11.7	-1.1
2013-01-01 01:00:00	10.7	-1.7
2013-01-01 02:00:00	9.9	-2.0
2013-01-01 03:00:00	9.3	-2.1
2013-01-01 04:00:00	8.8	-2.3
'''
temp.info()

'''
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 35064 entries, 2013-01-01 00:00:00 to 2016-12-31 23:00:00
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   LA      35062 non-null  float64
 1   NY      35064 non-null  float64
dtypes: float64(2)
memory usage: 821.8 KB
'''
temp_m = temp.resample('M', kind = 'timestamp').mean()
temp_m.head(12)

'''
LA	NY
datetime		
2013-01-31	11.596237	1.129570
2013-02-28	12.587202	0.617857
2013-03-31	15.069946	3.719220
2013-04-30	16.487361	10.699306
2013-05-31	19.005780	15.824328
2013-06-30	19.905417	22.225694
2013-07-31	22.093952	26.329704
2013-08-31	21.513172	22.480376
2013-09-30	22.404861	18.291806
2013-10-31	16.620430	14.335215
2013-11-30	15.107917	7.111944
2013-12-31	13.416935	2.776210
'''
temp_m.index

'''
DatetimeIndex(['2013-01-31', '2013-02-28', '2013-03-31', '2013-04-30',
               '2013-05-31', '2013-06-30', '2013-07-31', '2013-08-31',
               '2013-09-30', '2013-10-31', '2013-11-30', '2013-12-31',
               '2014-01-31', '2014-02-28', '2014-03-31', '2014-04-30',
               '2014-05-31', '2014-06-30', '2014-07-31', '2014-08-31',
               '2014-09-30', '2014-10-31', '2014-11-30', '2014-12-31',
               '2015-01-31', '2015-02-28', '2015-03-31', '2015-04-30',
               '2015-05-31', '2015-06-30', '2015-07-31', '2015-08-31',
               '2015-09-30', '2015-10-31', '2015-11-30', '2015-12-31',
               '2016-01-31', '2016-02-29', '2016-03-31', '2016-04-30',
               '2016-05-31', '2016-06-30', '2016-07-31', '2016-08-31',
               '2016-09-30', '2016-10-31', '2016-11-30', '2016-12-31'],
              dtype='datetime64[ns]', name='datetime', freq='M')
'''


## Advanced Indexing with reindex()

# 다시한번 짚고 넘어가자면 parse_dates = ['datetime']
# 이라고 해주는 것은 타입을 datetime으로 설정해준다는 의미다.

import pandas as pd
temp = pd.read_csv('temp.csv', parse_dates = ['datetime'], index_col = 'datetime')
temp.head()

'''
	LA	NY
datetime		
2013-01-01 00:00:00	11.7	-1.1
2013-01-01 01:00:00	10.7	-1.7
2013-01-01 02:00:00	9.9	-2.0
2013-01-01 03:00:00	9.3	-2.1
2013-01-01 04:00:00	8.8	-2.3
'''
temp_d = temp.resample('D').mean()
temp_d

'''
	LA	NY
datetime		
2013-01-01	8.858333	-0.404167
2013-01-02	9.283333	3.208333
2013-01-03	10.304167	-2.425000
2013-01-04	11.512500	-2.070833
2013-01-05	11.083333	0.816667
...	...	...
2016-12-27	12.154167	10.579167
2016-12-28	14.433333	4.016667
2016-12-29	16.045833	1.312500
2016-12-30	15.933333	2.204167
2016-12-31	13.275000	1.204167
1461 rows × 2 columns
'''
birthd = pd.date_range(end = '2016-12-24', periods = 3, freq = pd.DateOffset(years = 1))
birthd

# DatetimeIndex(['2014-12-24', '2015-12-24', '2016-12-24'], dtype='datetime64[ns]', freq='<DateOffset: years=1>')
temp_d.loc[birthd]

'''

LA	NY
2014-12-24	10.712500	8.045833
2015-12-24	10.716667	17.462500
2016-12-24	11.820833	4.045833
'''
temp_d.reindex(birthd)

'''
	LA	NY
2014-12-24	10.712500	8.045833
2015-12-24	10.716667	17.462500
2016-12-24	11.820833	4.045833
'''
temp_d.head()

'''
LA	NY
datetime		
2013-01-01	8.858333	-0.404167
2013-01-02	9.283333	3.208333
2013-01-03	10.304167	-2.425000
2013-01-04	11.512500	-2.070833
2013-01-05	11.083333	0.816667
'''

 

300x250