코딩하는 타코야끼

[Pandas] 6강_DataFrame_재구조화 본문

[T.I.L] : Today I Learned/Pandas

[Pandas] 6강_DataFrame_재구조화

가스오부시 2023. 4. 24. 20:22
728x90
반응형

1. 정돈된 데이터 (Tidy data) 개요

  • 대부분 실행환경에서의 많은 데이터 셋은 세부적 분석을 작업을 하기 전에 상당한 양의 데이터 재구성을 할 필요가 있다. 경우에 따라서는 전체 프로젝트 자체가 오로지 다른 사람들이 사용하기 쉬운 형태로 데이터를 재구성하는 일일 경우도 있다.
  • 데이터 재구성의 목적은 정돈된 데이터(tidy data) 를 만드는 것이다.Tidy data란 용어는 해들리 위컴이 분석이 용이한 형태로 구성되 있는 데이터셋을 설명하기 위해 만든 용어이다. 논문 링크

📍 정돈된 데이터란?

  • 각 변수(데이터의 속성)는 열을 형성한다.
  • 각 관측값(하나의 데이터)은 행을 형성한다.
  • 각 관측 단위별로 별도의 테이블(표)을 구성한다.
    • 단일 관측

🌓 변수

  • Feature, 컬럼, 속성
  • 데이터를 구성하는 요소들
  • 변수 이름
    • 성별, 인종, 연봉, 직위 같은 레이블
  • 변수 값
    • 관측 때마다 달라지는 값
      • 각 변수가 가질 수 있는 값
      • 성: 남성/여성
      • 인종: 황인/흑인/백인
      • 연봉: 삼천만원, 사천만원...
      • 키: 100.0 ~ 250.0

🌓  단일 관측

  • 하나의 관측단위(dataframe), 하나의 데이터를 말한다.
    • DataFrame(Pandas), Table(데이터베이스), Table(엑셀)로 표현된다.
  • 단일 관측 대상은 여러개의 속성들로 구성되며 그 속성을 변수라고 한다.
    • 단일 관측은 하나의 데이터 대한 모든 변수(속성)들의 모음
  • 예)
    • 고객, 제품, 계좌
  • 종업원정보(근무시간같은)와 고객정보(구매 액수)를 같은 테이블에 병합하는 것은 단일 관측이라 할수 없다. -> 정돈된 데이터의 원칙에 위배된다.

📍 정돈되지 않은 데이터의 가장 흔한 형태

🌓 경우의 수

  1. 열 이름이 변수 이름이 아니라 값인 경우
  2. 열 이름에 복수 개의 변수가 저장된 경우
  3. 변수가 행과 열에 모두 저장된 경우
  4. 같은 테이블에 복수의 관측단위가 저장된 경우
    • 하나의 테이블에 여러 데이터(관측단위)가 병합된 것
  5. 단일 관측 단위가 복수 테이블에 저장된 경우
    • 하나의 데이터의 변수들이 여러 테이블에 나눠 저장된 경우

🌓 데이터를 정돈한다의 의미

단순히 데이터셋의 값을 바꾸거나 결측치를 채운다는 것만을 말하지 않는다. 데이터를 정돈하는 것은 데이터의 형태나 구조를 정돈 원칙에 맞게 변형시키는 것이다.

  • 데이터가 올바른 형태로 주어진다면 분석이 쉬워진다.
  • 다양한 형태의 조회에 적용할 수 있도록 데이터셋을 만들어 준다.

 


2. Pandas의 정돈을 위한 메소드


📍 메소드( )

  • stack()
  • melt()
  • unstack()
  • pivot()
  • pivot_table()
  • crosstab()
  • 텍스트 분해를 위한 str accessor
  • 정돈된 데이터를 다듬는 메소드
    • rename()
    • rename_axis()
    • reset_index()
    • set_index()

📍 stack( )

  • 컬럼명을 index(행명)으로 전환
    • 기존 index가 있으면 하위 레벨로 들어간다. (기존 것이 상위 레벨)
  • 컬럼명을 컬럼의 값으로 전치시킬때도 사용할 수 있다.
  • 매개변수
    • dropna=False : 처리 시 생성되는 NA(결측치)는 제거되지 않게 한다. (default: True => 제거)
import pandas as pd
state_fruit = pd.read_csv('data/state_fruit.csv', index_col = 0)
state_fruit

# stack() => 컬럼명을 index 명으로 내린다.
s1= state_fruit.stack()
s1
>>>
Texas    Apple      12
         Orange     10
         Banana     40
Arizona  Apple       9
         Orange      7
         Banana     12
Florida  Apple       0
         Orange     14
         Banana    190
dtype: int64
# Series를 DataFrame 으로 변환(한개 컬러므이 DF)
s1.to_frame()
s1.to_frame(name = 'count') # 값의 컬럼명을 지정.

# 멀티 index 조회
s1['Texas'] #0번 level 기준 조회
s1.loc['Texas'] # Dataframe에서 행 조회시에는 loc을 사용해야함.
s1['Florida','Orange'] # 0번 level -> Florida, 1번 level->Orange => 두개 이상의 level 기준으로 조회 = > Tuple

# Orange 의 개수를 -> 1번 level 기준 조회(안쪽 index)
## xs() 메소드를 사용.
s1.xs('Orange',level=-1)
>>>
Texas      10
Arizona     7
Florida    14
dtype: int64
s1 = state_fruit.stack()
s_df = s1.reset_index()
s_df.columns = ['stage', 'fruit', 'count']
s_df


📍 unstack( )

  • stack() 반대로 index를 컬럼으로 변환한다.
  • 매개변수
    • level: multi-index일 경우 컬럼으로 만들 레벨을 지정한다. 기본값은 -1 로 가장 안쪽의 index를 이동시킨다.
s1.unstack() # -1 level dml index 를 컬럼으로 변경.

s2 = s1.unstack(level=0)

# axis의 이름을 지정(변경) -> axis 이름: 컬럼명 또는 index명 에 대한 이름
s3 = s2.rename_axis(columns='state', index = "fruits")

s3.stack().to_frame('count').reset_index()


📍 melt( ) - 컬럼명을 컬럼의 값으로 변환한다.

  • 컬럼 명을 단일 컬럼의 값으로 변환한다.
  • 변환할 컬럼들을 지정할 수 있어 stack()보다 더 유연하다.

매개변수

  • id_vars: 값으로 변환하지 않고 그대로 유지하고자 하는 컬럼명(열이름)들의 리스트
    • 식별변수라고도 한다.
    • 지정한 변수(컬럼)은 같은 열에 남게 되지만, value_vars에 전달된 각 열에 대해 반복적으로 나타난다.
  • value_vars: 단일 컬럼의 값으로 변경하고자 하는 컬럼명 리스트
    • value_vars에 지정한 컬럼이 value가 되고 그 컬럼의 값들은 다른 컬럼으로 생성된다.
    • id_vars를 지정하지 않고 value_vars만 지정하면 value_vars에 지정 안된 컬럼은 제거된다.
      • 제거 되지 않고 단독 컬럼으로 유지되길 바라는 컬럼은 id_vars로 지정한다.
  • var_name: value_vars로 단일열이 된 열의 이름 지정(지정 안하면 컬럼명은 variable)
  • value_name: value_vars에 지정된 열들의 값들이 변환된 컬럼의 이름 지정(지정안하면 컬럼명은 value)
    • index를 유지하려면 reset_index를 이용해 value로 뺀 뒤 해야 한다.
    • melt 한 경우 index명은 무시된다. => RangeIndex로 대체된다.
    • stack은 열이름을 index명으로 정돈(변경) 한다. </aside>
state_fruits2 = pd.read_csv('data/state_fruit.csv')
state_fruits2.rename({state_fruits2.columns[0]:'State'},axis=1, inplace = True)

# vars => 컬럼들
s = state_fruits2.melt(id_vars=['State'], # 값으로 변경하지 않고 컬럼으로 유지할 컬럼이름들을 지정.
                   value_vars=['Apple','Orange', 'Banana'], # 단일 컬럼의 값으로 변경할 컬럼이름들을 지정.
                 var_name='Fruits', # 컬럼명이 값으로 들어간 컬럼의 이름을 지정.
                  value_name= 'Count') # value들이 값으로 들어간 컬러므이 이름을 지정.

# id_vars 만 지정하면 지정되지 않은 나머지 컬럼들은 모두 값으로 변경된다.
state_fruits2.melt(id_vars=['State'],
                  var_name = 'Fruits', value_name = 'Count')

# id_ vars를 생략하면 value_vars 의 컬럼들을 제회한 나머지는 drop(제거) 시킨다.
state_fruits2.melt(value_vars = ['Apple', 'Orange'])

📍 pivot - index, column, value가 될 컬럼들을 지정해 재구조화

  • 데이터프레임 재구조화가 목적
  • 데이터 프레임에서 두개이상의 범주형 변수를 그룹으로 묶어 특정 값을 보려고 할때 사용할 수 있다.
    • pivot_table은 그룹으로 묶은 뒤 특정 변수의 통계량을 본다면 pivot은 그 값을 그대로 본다.
  • melt()된 것을 원상복구 시킬때도 사용할 수 있다.

🌓  pivot 매개변수

  • index: 문자열. 행이름으로 사용할 컬럼 -> 열이 index로 이동하는 형태가 된다.
  • columns: 문자열. 컬럼명으로 사용할 컬럼
  • values : Value에 올 컬럼명
  • DataFrame “s”

df = s.pivot(index="State",  #index에 놓을 컬럼
            columns = 'Fruits', #columns 에 놓을 컬럼이름
            values = "Count")# 값으로 사용할 컬럼. # index 값, 컬럼의 값이 교차하는 지점의 value가 값이 된다.


📍 crosstab()

  • 범주형 값들 고유값 별 빈도표를 만든다.

🌓  매개변수

  • index: 행에 들어올 1차원 배열
  • columns: 열에 들어올 1차원 배열
  • rownames: index 이름 지정. 생략하면 index의 고유값들로 설정된다.
  • colnames: column 이름 지정. 생략하면 columns의 고유값들로 설정된다.
  • margins: 총합계 행과 열을 추가할지 여부. True-추가, False-추가안함(기본값)
  • normalize: 빈도수를 비율로 나타낸다.
import numpy as np
np.random.seed(0)
d = {
    "직업":np.random.choice(["학생",'자영업','회원'], 7, p=[0.5, 0.3, 0.2]), # 학생, 자영업, 회사원 =>7
    "혈액형": np.random.choice(["A","B"], 7),
    "합격여부": np.random.choice(['합격', '불합격'], 7)}
df = pd.DataFrame(d)

pd.crosstab(index =df['직업'],  # index에 위치시킬 컬럼(범주형)
           columns=df["혈액형"]) # column에 위치시킬 컬럼(범주형)

pd.crosstab(index = df['직업'], columns = [df['혈액형'], df['합격여부']])

반응형