본문 바로가기
프로그래밍/Python 관련 정보

[Pandas] 데이터 재구조화

by TrillionNT 2025. 2. 23.

2025.02.24 - [프로그래밍/Python 관련 정보] - [Pandas] Table of Contents


 

 

Pandas DataFrame의 데이터 재구조화 방법에 대해서 살펴보겠습니다. 어떤 방법론을 사용할지 결정하는 것은 현 데이터프레임이 multiindex구조인지, 어떤 칼럼을 가지고 있는지 목적이 무엇인지에 따라 판단하시면 되겠습니다. 방법론의 적용에 있어 데이터프레임의 정렬여부는 크게 중요하지 않습니다. 

 

1. Pivot

  • 지정된 인덱스, 열, 값을 사용하여 새로운 형태의 DataFrame 생성.
  • 기존 DataFrame에서 세 칼럼(index로 지정할 칼럼, columns로 변환할 칼럼, values로 설정할 칼럼) 필요.
  • 기존 데이터가 (index, column) 조합에서 고유(unique)해야 하며, 중복이 있으면 pivot()을 사용할 수 없음.
df.pivot(index='행 인덱스 칼럼', columns='칼럼 인덱스 칼럼', values='값 칼럼')
더보기

참고) 중복이 존재할 경우 Pivot_table 활용하여 집계하는 방법

df = pd.DataFrame({
    'group': ['A', 'A', 'A', 'B', 'B'],
    'category': ['X', 'X', 'Y', 'X', 'Y'],
    'value': [10, 15, 20, 30, 40]
})

# pivot()은 오류 발생 → 중복 존재
df_pivot_table = df.pivot_table(index='group', columns='category', values='value', aggfunc='mean')
print(df_pivot_table)

 

2-1. Stack

  • 마지막 레벨(Default값; -1)의 칼럼을 행 레벨(인덱스)로 변환.
  • 다중 인덱스()를 생성하며, 결과는 주로 Series나 더 높은 차원의 인덱스를 가진 DataFrame.
df.stack(level=-1, dropna=True)

 

2-2. Unstack

  • 마지막 레벨 (Default값; -1) index가 칼럼으로 이동.
  • MultiIndex 구조에서만 동작하며, 인덱스의 특정 레벨을 칼럼으로 변환하여 wide type 형태의 DataFrame을 생성.
df.unstack(level=-1, fill_value=None)


3. Melt

  • 여러 열을 두 열(변수명과 값)로 재구조화하여 데이터를 더 좁고 긴 형태( long format )로 변환.
df.melt(id_vars=None, value_vars=None, var_name=None, value_name='value', col_level=None, ignore_index=True)
  • id_vars : 기준이 될 열
  • value_vars : 기준열에 대한 하위 카테고리를 나열할 열
  • var_name : 카테고리들이 나열된 열의 이름을 설정
  • value_name : 카테고리들의 값이 나열될 열의 이름을 설정
  • col_leve : multi index의 경우 melt를 수행할 레벨을 설정
  • ignore_index : 인덱스를 1,2,3, ... , n으로 설정할지 여부

 

예시를 통해서 좀 더 이해해보겠습니다. 

import pandas as pd

df = pd.DataFrame({
    'date': ['2025-02-23', '2025-02-23', '2025-02-24', '2025-02-24'],
    'city': ['Seoul', 'Busan', 'Seoul', 'Busan'],
    'temperature': [10, 12, 11, 13],
    'humidity': [60, 65, 58, 62]
})

print("Original DataFrame:")
print(df)

 

최초의 데이터프레임은 아래와 같은 형태라고 해보겠습니다. 

저는 상당히 헷갈렸던 부분이라 사족을 달아보면, city(columns의 argument)가 Seoul, Busan, Seoul, Busan으로 정렬되어 있든 Seoul, Seoul, Busan, Busan으로 정렬되어 있든 크게 중요하지 않습니다.

 

이 데이터프레임을 Pivot해보면 

사실 여기서는 values를 temperature, humidity 2개를 넣었는데 Pivot의 설명을 위해 temperature만 집중해서 표시했습니다. 여러개의 value를 넣어도 적용 원리는 동일합니다.

df_pivot = df.pivot(index='date', columns='city', values=['temperature', 'humidity'])
print("\nAfter pivot:")
print(df_pivot)

 

이 결과물을 다시 Stack해보겠습니다. Stack은 칼럼을 index로 녹이는 작업이라고 말씀드렸습니다. 

df_stacked = df_pivot.stack(level=-1)
print("\nAfter stack:")
print(df_stacked)

 

이름 그대로 이렇게 나온 결과물을 다시 unstack하면 돌아갈 수 있습니다. 

df_unstacked = df_stacked.unstack(level=-1)
print("\nAfter unstack:")
print(df_unstacked)

 

 

이번에는 처음 데이터프레임에서 melt를 수행해보겠습니다. 저 같은 경우에는 Tableau에 데이터를 넣기 전에 이런꼴로 바꾸어주는 경우가 많습니다. 원래는 칼럼에 흩어져있던 변수들을 최대한 압축해서 행으로 구분하게 만드는 작업입니다. '변수명'이라는 새로운 칼럼을 만들어서 카테고리 구분을 (행단위로) 해주고, 그 카테고리에 대해서 값이 입력되는 단하나의 칼럼을 남기는 방식입니다. var_name(카테고리 구분 칼럼)과 value_name(값 칼럼)의 이름은 우리가 지정해주어야 합니다. 

 

df_melted = pd.melt(df, id_vars=['date', 'city'], value_vars=['temperature', 'humidity'], var_name='measurement', value_name='value')
print("\nAfter melt:")
print(df_melted)