본문 바로가기
개발일지/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