본문 바로가기
Programming/python

파이썬 pandas.melt() 데이터 재구조화(reshape) ( melt vs pivot )

by 조창대 2021. 10. 13.
반응형

데이터 재구조화, 전처리 과정에서 pivot과 함께 melt 함수도 많이 사용된다. 하지만 pivot()과는 반대로 작동함.  

 

  • 간단하게 말해서 melt()는 dataframe format을 wide에서 long으로 바꿔주는 함수이다. 그래서 wide_to_long() 메서드와 함께 쓰이기도 한다. 인덱스와 열을 녹여 하나 혹은 다수의 컬럼이 identifier가 되어 dataframe을 specific format으로 재구조화한다. 원래 df의 형식이 녹여지고 식별변수(id_variable)을 기준으로 정렬된다고 생각하면 된다. 
  • 반면에 pivot()은 여러 형태로 이루어진 dataframe에 index, columns, values를 각각 지정해주어 melt된 df를 보기 좋은 형태로 재구조화 시켜주는 메서드이다. 즉, unmelt의 개념이다.

 


melt()

pandas.melt(frameid_vars=None, value_vars=None, var_name=None, value_name='value', col_level=None, 

ignore_index=True)

 

pandas documentation에 명시된 melt의 파라미터다. 

frame 자리엔 바꿀 df를 넣어주고, id_vars에는 ID 변수를 지정해준다.

melt는 ID 변수를 기준으로 원래 데이터셋에 있던 컬럼명들을 'variable' 컬럼의 값들로 위에서 아래로 길게 나열하고, 'value' 컬럼에 ID 변수와 variable에 있는 값대로 차례차례 넣어주는 식으로 작동한다. 

value_vars는 'value' 컬럼에 들어가는 값을 지정해준다. 

 

 

import pandas as pd

df=pd.DataFrame({'store':['Costco','Costco','Costco','Wal-Mart','Wal-Mart','Wal-Mart',"Sam's Club","Sam's Club","Sam's Club"],
               'product':['Potato','Onion','Cucumber','Potato','Onion','Cucumber','Potato','Onion','Cucumber'],
               'price':[3000,1600,2600,3200,1200,2100,2000,2300,3000],
                'quantity':[25,31,57,32,36,21,46,25,9]})
df

예시를 위해 야채를 파는 가게의 이름과 야채 이름, 가격, 갯수를 나타내는 df를 형성한다.

 

이 df의 store, product 열을 식별변수(id_variable)로 지정하여 melt() 함수를 써보면,

df.melt(id_vars=['product','store'])

이렇게 product와 store을 제외한 열들이 새롭게 생성된 'variable' 열의 값들로 쭉 나열되고, 'variable' 의 값에 따른 데이터들이 'value' 열에 나열된다.

컬럼에 있던 price와 quantity가 열로 주르륵 녹아서 인덱스별로 데이터를 볼 수 있게 전처리가 되었다.

 

출처: https://pandas.pydata.org/pandas-docs/stable/user_guide/reshaping.html#reshaping-by-melt

 

df.melt(id_vars=['product','store'],value_vars='quantity')

'value' 열에 들어갈 값들을 지정해주면 'variable' 열과 'value' 열에도 그 데이터들만 나타난 것을 확인할 수 있다. 

 

 

var_name과 value_name 파라미터는 scalar로 지정할 수 있다. (scalar는 quantity, speed, distance같이 수치, 크기는 있지만 방향성이 없는 것을 뜻함)

쉽게 말해서 'variable'과 'value' 열의 이름을 정해주는 것이다.

df.melt(id_vars=['product','store'],
	var_name='product_info',value_name='product_value')

 


pivot()

pivot()은 위처럼 melt()되거나 해서 여러 형식으로 뒤죽박죽인 데이터프레임을 구별하기 쉽게 바꾸고 싶을 때 사용한다. 

 

df

 

다시 원본 df를 가져왔다. df에 index, column, value를 각각 지정해서 피봇해보자.

 

 

df.pivot(
    index='product',
    columns='store',
    values='Price')

야채 이름과 야채를 파는 스토어가 교차하는 지점의 야채 가격들이 알맞게 들어가 있다.

 

출처: https://pandas.pydata.org/pandas-docs/stable/user_guide/reshaping.html#reshaping-by-melt

참고로 pivot() 함수는 df.pivot(index='product',columns='store',values='Price') 했을 때 product가 potato인 Costco가 2개 이상일 땐 ValueError: Index contains duplicate entries, cannot reshape 이런 에러가 뜬다. 

pivot()은 index 데이터와 columns나 values 데이터의 조합? 중 중복되는 게 있으면 에러가 뜬다. 그럴 땐 중복되지 않게 데이터프레임을 정제해주거나, pivot_table()을 써서 해결한다. 

피벗테이블은 데이터를 요약하고 분석하여 요약 데이터를 제공하는데 유용하다. 

 

 

정리하자면 pivot()이 인덱스와 행, 열을 하나하나 지정해서 데이터를 재구조화/보기 좋게 구축화하는 것이라면,

melt()는 ID 변수를 하나 혹은 여러 개 지정해서 그것들을 기준으로 나머지 열의 이름과 열 값들을 아래로 쭉 나열하여 재구조화한다. melt()를 쓰면 얇고 긴 데이터프레임이 만들어 진다. 

반응형