데이터프레임 변경(4): Rolling과 Shift / Pivot과 Melt

2024. 9. 26. 17:09·데이터 분석/Pandas 기초
목차
  1. 1. Rolling
  2. 1) 일상적인 집계
  3. 2) Rolling 집계
  4. 2. Shift
  5. 3. Rolling & Shift
  6. 4. 참고: 내일의 Ozone 값을 예측하려면?
  7. 5. Pivot
  8. 6. Melt

1. Rolling


rolling() 메서드를 사용하면 일정 기간에 대한 집계를 수행할 수 있다. 예를 들어 최근 3일간 혹은 일주일 간의 평균이나 합을 집계 가능하다. 우선 일상적으로 우리가 하는 집계부터 살펴보자.

 

1) 일상적인 집계

일상적으로는 특정 열의 평균이나 합 등과 같은 집계를 수행한다. 전체 평균을 이런 식으로 집계해서 새로운 열로 만들어주면, 이후에 전체 평균 대비 오존 농도 평균이 얼마인지에 대해 시각화해볼 수도 있다. 

# 새로운 열 추가
air['OZ_mean'] = round(air['Ozone'].mean(), 1)

 


 

2) Rolling 집계

시계열 데이터의 경우, 최근 일정 기간에 대한 집계가 필요할 수 있다. 

이때 rolling() 메서드를 적용하게 되는데, 특정 창(window)을 기준으로 이동 평균, 이동 합계 등과 같은 집계 작업을 수행한다.

 

지정해줘야 하는 매개변수
- window 매개변수에 대한 대상 행 수를 지정: 매개변수 이름 생략 가능
- min_periods 매개변수에 몇 개의 행만 있어도 집계를 수행할지 지정

 

# 최근 3일간 Ozone 열 평균
air['Ozone'].rolling(3).mean()

 

테이블이 있는데, 위 세 개 행의 평균을 출력하고 있는 것이기에 0번 행과 1번 행은 값이 없는 것이다. 만약 이것들도 값을 채워주고 싶다면, min_periods=1로 해서 3개가 아니라 값이 하나만 있어도 평균을 내게 해라. 하고 재정해줄 수 있다. 단위를 뭘로 볼 것인지는 window로 지정해준다. 

# 최근 3일간 Ozone 열 평균
air['Ozone'].rolling(window=3, min_periods=1).mean()

# 최근 7일간 Ozone 열 평균
air['Ozone'].rolling(window=7, min_periods=1).mean()

이런 집계 결과를 새로운 열로 추가해 분석에 활용할 수 있다. 예를 들어 당일 Ozone 열 값을 최근 3일 또는 7일간의 평균과 비교할 수 있다. 

# 새로운 열 추가
air['OZ_mean_3'] = round(air['Ozone'].rolling(window=3, min_periods=1).mean(), 1)
air['OZ_mean_7'] = round(air['Ozone'].rolling(window=7, min_periods=1).mean(), 1)

OZ_mean_7의 29.7 값은 오늘 포함 최근 3일의 오존 평균이다. 0번 행의 41.0은 자기 자신이다. 38.5는 0행과 1행 오존 농도의 평균이다.

 

최근 3일의 평균과 7일의 평균은 오존 농도를 예측하는데 도움이 될까 안될까?
도움이 엄청 된다. 시계열 데이터 예측할 경우, 전처리 과정에서 이런 추가적인 열들을 더 많이 만들어낼 수 있다.
전날 오존농도, 전전날 오존농도가 있으면 내일의 오존농도를 예측하는 데 중요한 의미를 가진다. 이런 것들을 담는 추가적인 열을 만들어내는 것을 피처 엔지니어링이라고 한다. 전처리에 들어가는 아주 고급 기술이라고 할 수 있다.

 


 

2. Shift


데이터를 행 방향 또는 열 방향으로 이동시킬 때 shift() 메서드를 사용한다. 이 메서드는 데이터를 특정 행이나 열 방향으로 이동시켜, 시계열 데이터에서 이전 값과 비교하는 데 사용한다. 

# 새로운 열 추가
air['OZ_lag_1'] = air['Ozone'].shift(1)
air['OZ_lag_2'] = air['Ozone'].shift(2)
air['OZ_lag_3'] = air['Ozone'].shift(3)

결과 해석
- shift의 결과 OZ_lag_1, 2, 3이 있다. (보통 lag는 이전 데이터를 얘기하고, lead는 나중 데이터를 가리킨다.)
- OZ_lag_1에서 41.0은 어제의 오존 농도를 가져온 것이다.
- OZ_lag_2는 그제의 오존 농도이다.
- 인덱스 4의 입장에서 보자. OZ_lag_1에서 18.0은 어제의 오존농도이다. 12.0은 그제의 오존농도이다. 36.0 이건 그제의 오존농도이다.
- 이것을 가지고 내일의 오존농도를 예측할 때 큰 역할을 할 수 있지 않을까?
- 이후 데이터 분석 단계에서 과연 이런 값들이 어떤 값을 설명하는 데 의미가 있나를 판별하게 되며, 의미가 없으면 그때 지워버리면 된다.
- 한편, 내일의 값을 땡겨오려고 하면, `shift(-1)`이라고 하면 된다. 

 


3. Rolling & Shift


rolling(), shift() 메서드를 같이 사용할 수도 있는데, 일반적으로 당일을 제외한 기간에 대한 rolling을 수행할 때 사용한다.
다음 구문은 당일을 제외한 최근 3일간의 Ozone 값 평균을 갖는 열을 추가하는 구문이다.

 

# 새로운 열 추가
air['OZ_mean_3_lag_1'] = round(air['Ozone'].rolling(3, min_periods=1).mean().shift(1), 2)

 

OZ_mean_3은 오늘을 포함해서 최근 3일의 오존 평균이다. 그런데, 어제부터 포함해서 그제 그그제를 포함한 3일 평균을 옆에 추가하고 싶다면?
- OZ_mean_3에서 바로 위의 값을 옆의 열로 추가하면 된다.
- 즉, rolling한 것을 shift하면 되는 것이다. 이게 맨 마지막 열의 의미이다. 

 

 

4. 참고: 내일의 Ozone 값을 예측하려면?


내일의 Ozone 값을 예측하는 머신러닝 모델을 만들 때는 1일 후 값을 각 행에 추가해야 한다.
즉, 당일 Ozone, Temp, Solar.R, Wind 정보와 최근 Ozone 값과 Ozone 값 평균 등을 활용해 다음 날 Ozone 값을 예측하게 할 수 있다.

# 새로운 열 추가: 다음날 Ozone 값 (예측 대상)
air['OZ_lead_1'] = air['Ozone'].shift(-1)

# 불필요한 열 제거
air.drop(['Month', 'Day'], axis=1, inplace=True)

 

결과 해석
- OZ_lead_1에서 0행에 있는 36.0은 내일의 오존농도이다.
- 그런데 28.0이 이 데이터프레임의 맨 마지막 행이라면? 그다음은 예측을 해야 한다. 그게 28.0인데, 이것을 맞추라고 하는 게 머신러닝이다.
- 실제 봤더니 어떻게 되었는가. 이정도면 맞췄다. 할 수도 있고. 계속 3일 뒤를 관찰하면서 수정해나갈 수 있다. 이게 바로 시계열 데이터이다. 

 


 

5. Pivot


pivot() 메서드를 사용해 피벗 형태로 변경 가능하다.

# 데이터 읽어오기
bike = pd.read_csv('BikeFile.csv')

# datetime으로 바꾸기
bike['DateTime'] = pd.to_datetime(bike['DateTime']) 

# Year, Month, Day, Hour 분리
bike['Year'] = bike['DateTime'].dt.year
bike['Month'] = bike['DateTime'].dt.month
bike['Day'] = bike['DateTime'].dt.day
bike['Hour'] = bike['DateTime'].dt.hour

# 데이터 선택
bike = bike.loc[:, ['Year', 'Month','Day', 'Hour', 'Count']]

# 년월일별 수요량 집계
day_count = bike.groupby(by=['Year', 'Month', 'Day'], as_index=False)[['Count']].sum()

 

위에서 일별이었던 것을 일(1~365)에 대해서 가로 칼럼으로 만들어버린다. 이러면 와이드하게 바꾸어서 한눈에 볼 수 있다. 이를 위해 pivot() 메서드를 사용해 위 결과 형태를 피벗 형태로 변환할 수 있다. 

 

매개변수
- index: 움직이지 않을 열(=기준 열)
- columns: 새로운 열로 올라갈 현재 열
- values: 새로운 열의 값이 될 현재 열

 

# 피벗 형태로 변환
# index는 움직이지 마. 컬럼으로 올라갈 애는 day야. 그리고 count는 그 각각의 값으로 들어가라!
day_count_w = day_count.pivot(index=['Year', 'Month'], columns='Day', values='Count')

# 열 대표이름 제거('컬럼에 대한 이름이다. 나 왕년에 'day'였어! ---> 이거 지워준다. 마치 인덱스 이름 지우는 것과 같다.)
day_count_w.columns.name = None

# 인덱스 초기화
day_count_w.reset_index(drop=False, inplace=True) # 인덱스 초기화하여서 일반 열로 가라.

 


 

6. Melt


위의 pivot() 결과를 역으로 바꿔주는 것을 melt()라고 한다.

시각화 분석을 위해서는 이전의 형태로 돌려야 하는 경우가 많다. 

 

매개변수
- id_vars: 움직이지 않을 열(=기준 열)
- value_vars: 값이 되어 아래로 내려올 현재 열(생략하면 id_vars에 지정한 열 이외의 모든 열)
- var_name: value_vars에 지정한 열이 값이 될 때 부여할 열 이름(생략하면 variable)
- value_name: 새로운 열이 되는 기존 값에 부여할 열 이름(생략하면 value)

 

# 언피벗
day_count_n = pd.melt(day_count_w, 
                      id_vars=['Year', 'Month'],
                      # value_vars=range(1, 32),
                      var_name='Day',
                      value_name='Count')

# 정렬
day_count_n.sort_values(by=['Year', 'Month', 'Day'], ascending=True, inplace=True)

# 결측치 제거(31일이 꽉 차지 않는 월에 결측치 존재)
day_count_n.dropna(inplace=True)

# 인덱스 초기화
day_count_n.reset_index(drop=True, inplace=True)

# 데이터 형식 변경
day_count_n['Count'] = day_count_n['Count'].astype(int)

 

'데이터 분석 > Pandas 기초' 카테고리의 다른 글

데이터프레임 변경(3): 합치기(Concat)와 조인(Merge)  (1) 2024.09.25
데이터프레임 변경(2): 결측치 처리 / 가변수(Dummy Variable) 생성  (0) 2024.09.25
데이터프레임 변경(1): 열(이름변경, 추가, 삭제) / 범주값(변경, 생성)  (1) 2024.09.24
데이터프레임 생성, 탐색, 조회, 집계  (2) 2024.09.23
넘파이 배열의 기본 개념  (1) 2024.09.21
  1. 1. Rolling
  2. 1) 일상적인 집계
  3. 2) Rolling 집계
  4. 2. Shift
  5. 3. Rolling & Shift
  6. 4. 참고: 내일의 Ozone 값을 예측하려면?
  7. 5. Pivot
  8. 6. Melt
'데이터 분석/Pandas 기초' 카테고리의 다른 글
  • 데이터프레임 변경(3): 합치기(Concat)와 조인(Merge)
  • 데이터프레임 변경(2): 결측치 처리 / 가변수(Dummy Variable) 생성
  • 데이터프레임 변경(1): 열(이름변경, 추가, 삭제) / 범주값(변경, 생성)
  • 데이터프레임 생성, 탐색, 조회, 집계
KURIKU
KURIKU
학습을 기록하기 위한 공간입니다.
  • KURIKU
    꾸리 log
    KURIKU
  • 전체
    오늘
    어제
    • 학습기록 (113)
      • 독서 (5)
        • 데이터 분석을 위한 SQL 레시피 (5)
      • 데이터 분석 (44)
        • 기타 환경 설정 (3)
        • 파이썬 기초 (11)
        • Pandas 기초 (6)
        • 비즈니스 데이터 분석 (3)
        • 웹 크롤링 (2)
        • 데이터 시각화 (0)
        • 머신러닝 (7)
        • 딥러닝 (7)
        • IT 인프라 (5)
        • 클라우드 서비스 (0)
        • 제안서 작성 (0)
      • AIBLE SCHOOL 6기_DX 컨설턴트 과정 (45)
        • 사전학습 (25)
        • 본 학습 (20)
      • 데이터리안 SQL 캠프 (0)
        • 입문반 (0)
        • 심화반 (0)
      • UXUI 심리학 (0)
      • 기업분석, 취준 (1)
      • 관심산업 경제뉴스브리핑 (16)
        • 카드산업 (6)
        • IT산업 (9)
        • 헬스케어산업 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    2차 미니프로젝트
    kt aivle school
    분당교육장
    kt aible school
    kt aivle school#기자단#6기
    에이블스쿨
    kt aible
    DX 컨설턴트 트랙
    4차 미니프로젝트
    6기
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
KURIKU
데이터프레임 변경(4): Rolling과 Shift / Pivot과 Melt

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.