Dataframe 날짜 기준으로 데이터 조회
데이터 분석 시 일정 시간에 저장된 시계열 데이터를 처리하거나, 특정 기간 (예를 들어, 최근 한 달 또는 두 달간) 데이터를 기준으로 통계치를 산출하고자 할 때 날짜 기준으로 데이터를 필터링하고 처리하는 것이 필요합니다. Pandas Dataframe에서는 아래와 같이 다양한 방법으로 날짜 기준의 데이터 행의 선택 가능합니다. 직관적으로로 이해가 쉬운 것은 isin() 함수와 between() 함수이고, 다양한 조건의 데이터 (예를 들어, 매주 월요일, 매주 1일 기준, 일주일 기간)를 얻어오는 함수는 query()가 적절합니다.
- pandas.DataFrame.isin()은 두 날짜 사이에서DataFrame 행을 선택
- pandas.Series.between()은 두 날짜 사이에서 DataFrame행을 선택
- Bool mask를 선언하고 두 날짜 사이의 행을 pandas.DataFrame.loc(mask)으로 선택
- pandas.DataFrame.query() 문으로 행을 선택
실제 사용 가능한 샘플 코드와 결과는 아래와 같습니다. CSV나 데이터를 선언할 때 string (or dtobject) 에서 datatime으로 형 변환을 꼭 해야 합니다.
import pandas as pd
data = [
['2021-01-01', 1],
['2021-02-01', 2],
['2021-03-01', 3],
['2021-04-01', 4],
['2021-05-01', 5],
['2021-06-01', 6],
['2021-07-01', 7],
]
df = pd.DataFrame(data, columns=['Date', 'Value'])
df['Date'] = pd.to_datetime(df['Date'])
print (df.dtypes,'\n')
→ 실행 결과: Date column을 datetime으로 형변환 합니다.
→ 실행 결과: data를 dataframe으로 변경한 값입니다. Date와 Valume column으로 구성되었고, 날짜별 0~6번 행의 데이터가 있습니다.
# 방법 #1. isin() 함수 사용합니다. 시작 날짜와 끝나는 날짜를 지정해서 data_range() 함수 호출합니다. df['Date'].isin() 함수는 날짜에 따라서 boolean list로 return 합니다.
df_filered = df[ df['Date'].isin(pd.date_range('2021-02-01', '2021-05-01')) ]
# 방법 #2. pandas.Series.between() 함수를 사용
df_filered = df [df['Date'].between('2021-02-01', '2021-05-01')]
# 방법 #3. 시작 날짜와 종료 날짜를 기준으로 boolean mask를 정의하고 df.loc [mask]로 지정
mask = (df['Date'] >= '2021-02-01') & (df['Date'] <= '2021-05-01')
filtered = df.loc[mask]
# 방법 #4. 날짜 열을 인덱스 열로 설정하여 통합df.loc[start_date : end_date]방법을 사용하여 위의 프로세스를 단순화
df = df.set_index(['Date'])
filtered= df.loc['2021-02-01':'2021-05-01']
#방법 #4. query()
filtered=df.query("Date >= '2021-02-01' and Date <='2021-05-01'")
→ 실행 결과: 방법#1~4번까지 모두 동일한 결과를 얻습니다. 2월부터 5월까지의 행을 가져옵니다.
Dataframe 날짜 기준으로 데이터 조회
날짜 range 대신 특정 요일 또는 달을 기준으로 데이터 행을 선택하는 방법입니다. datatime의 dayofweek, day, month, year 기준으로 데이터를 선택할 수 있습니다. dt.dayofweek (요일)은 월요일 0, 화요일일 1로 맵핑되어 토요일은 5, 일요일은 6으로 정의되어 있습니다. dataframe.query() 문에 boolean 조건을 구성해야 하고, 변수로 지정하는 경우에는 @variable으로 string query문을 구성합니다.
#query() - 매주 월요일의 데이터 선택하기
filtered2 = df.query('Date.dt.dayofweek == 0')
print ('월요일인 경우:')
print (filtered2, '\n')
→ 실행 결과: Dataframe 에서 'Date' column을 기준으로 월요일인 경우만 데이터 행을 선택합니다.
#query() - 5월인 경우
query_month = 5
filtered3 = df.query('Date.dt.month == @query_month')
print ('5월인 경우:')
print (filtered3, '\n')
→ 실행 결과: ataframe 에서 'Date' column을 기준으로 datetime의 month가 5인 경우만 데이터 행을 선택합니다. 즉 5월 데이터를 추출합니다.
본 포스트팅의 샘플 코드는 아래와 같고, GitHub Repository에도 반영되어 있습니다.
import pandas as pd
def test6():
data = [
['2021-01-01', 1],
['2021-02-01', 2],
['2021-03-01', 3],
['2021-04-01', 4],
['2021-05-01', 5],
['2021-06-01', 6],
['2021-07-01', 7],
]
df = pd.DataFrame(data, columns=['Date', 'Value'])
df['Date'] = pd.to_datetime(df['Date'])
print (df.dtypes,'\n')
print(df, '\n')
df_filered = df[ df['Date'].isin(pd.date_range('2021-02-01', '2021-05-01')) ]
print (df_filered, '\n')
df_filered = df [df['Date'].between('2021-02-01', '2021-05-01')]
print (df_filered, '\n')
mask = (df['Date'] >= '2021-02-01') & (df['Date'] <= '2021-05-01')
filtered = df.loc[mask]
print (df_filered, '\n')
# 날짜 열을 인덱스 열로 설정하여 통합df.loc[start_date : end_date]방법을 사용하여 위의 프로세스를 단순화
df = df.set_index(['Date'])
filtered= df.loc['2021-02-01':'2021-05-01']
print (df_filered, '\n')
#query()
filtered=df.query("Date >= '2021-02-01' and Date <='2021-05-01'")
print (df_filered, '\n')
#query() - 매주 월요일
filtered2 = df.query('Date.dt.dayofweek == 0')
print ('월요일인 경우:')
print (filtered2, '\n')
#query() - 5월인 경우
query_month = 5
filtered3 = df.query('Date.dt.month == @query_month')
print ('5월인 경우:')
print (filtered3, '\n')
관련 글:
[SW 개발/Data 분석 (RDB, NoSQL, Dataframe)] - Pandas Dataframe 여러 열과 행에 apply() 함수 적용 (Sample code 포함)
[SW 개발/Python] - Python: JSON 개념과 json 모듈 사용법
[SW 개발/REST API] - 자주 사용하는 curl 명령어 옵션과 예제
[SW 개발/Data 분석 (RDB, NoSQL, Dataframe)] - MariaDB의 Python Connector 설치와 사용 방법
[SW 개발/Data 분석 (RDB, NoSQL, Dataframe)] - Jupyter Notebook의 업그레이드: Jupyter Lab 설치 및 extension 사용법
댓글