이번 포스팅에서는 Python pandas 의 Series, DataFrame의 행(row)과 열(column)에 대해서

 

 - 생성 (creation)

 - 선택 (selection, slicing and indexing)

 - 삭제 (drop, delete)

 

하는 방법에 대해서 알아보겠습니다.

 

외부 데이터셋을 불러오거나 직접 만든 다음에 데이터 전처리하는데 있어 수시로 사용하는 가장 기본이 되는 데이터 조작 기법이 행, 열 생성, 선택, 삭제입니다.

 

그동안의 포스팅을 따라해보신 분이라면 이미 많이 익숙해졌을 텐데요, 체계적으로 정리도 해보고, 복습도 해볼 겸 예를 들어서 설명해보겠습니다.

 

 

 

 

 

  (1) Series 생성 및 Series 원소 선택 (element selection, indexing)

 

pd.Series() 를 써서 별도의 index label 이 없는 간단한 Series 를 만들어 보겠습니다.

(index는 0, 1, 2, ... 정수가 자동 부여됨)

 

 

# importing library

In [1]: import numpy as np


In [2]: import pandas as pd

 


# pd.Series with ndarrary data

In [3]: Seri = pd.Series([0., 1., 2., 3., 4.])


In [4]: Seri

Out[4]:

0    0.0
1    1.0
2    2.0
3    3.0
4    4.0
dtype: float64

 

 

 

 

이제 Series의 index 위치나 조건을 가지고 indexing 을 해보겠습니다.

 

 

# Slicing pd.Series like ndarray-like

In [5]: Seri[0]

Out[5]: 0.0


In [6]: Seri[:3]

Out[6]:

0    0.0
1    1.0
2    2.0
dtype: float64


In [7]: Seri[Seri >= Seri.mean()]

Out[7]:

2    2.0
3    3.0
4    4.0
dtype: float64


In [8]: Seri[[4, 2, 0]]

Out[8]:

4    4.0
2    2.0
0    0.0
dtype: float64

 

 

 

 

다음으로, index에 label을 할당해준 Series를 만들어보고, 특정 index label을 지정해서 indexing을 해보겠습니다.

 

 

# pd.Series with index name passed

In [9]: Seri_ix = pd.Series([0., 1., 2., 3., 4.], index=['a', 'b', 'c', 'd', 'e'])


In [10]: Seri_ix

Out[10]:

a    0.0
b    1.0
c    2.0
d    3.0
e    4.0
dtype: float64

 


# Slicing with index label

In [11]: Seri_ix[['a', 'b', 'e']]

Out[11]:

a    0.0
b    1.0
e    4.0
dtype: float64


In [12]: Seri_ix.get(['a', 'b', 'e']) # get() method

Out[12]:

a    0.0
b    1.0
e    4.0
dtype: float64

 

 

 

 

특정 index label 을 지정해서 값(value)을 할당해보겠습니다.

 

 

# set values by index label
In [13]: Seri_ix['a'] = 100


In [14]: Seri_ix

Out[14]:

a    100.0
b      1.0
c      2.0
d      3.0
e      4.0
dtype: float64

 

 

 

 

특정 index label 이 Series에 들어있는지 아닌지 확인 (boolean True, False) 해보겠습니다.

 

 

# check index label whether it is or is'not in Series

In [15]: 'a' in Seri_ix

Out[15]: True


In [16]: 'x' in Seri_ix

Out[16]: False

 

 

 

 

 

  (2) DataFrame 행과 열 생성, 선택, 삭제 (creation, selection, drop of row and column)

 

예제로 사용할 간단한 DataFrame을 dict 로 칼럼과 값을 매핑하고, index 를 지정해서 만들어보겠습니다. DataFrame.index 로 index 확인, DataFrame.columns 로 칼럼 확인할 수 있습니다.

 

 

# importing library and making an example DataFrame

In [17]: from pandas import DataFrame


In [18]: df = DataFrame({'C1': [0., 1., 2., 3.],

    ...: 'C2': [4., 5., 6., 7.],

    ...: 'C3': [8., 9., 10., np.nan]},

    ...: index=['R1', 'R2', 'R3', 'R4'])

    ...:


In [19]: df

Out[19]:

     C1   C2    C3
R1  0.0  4.0   8.0
R2  1.0  5.0   9.0
R3  2.0  6.0  10.0
R4  3.0  7.0   NaN

 


# the row and column labels

In [20]: df.index # row labels

Out[20]: Index(['R1', 'R2', 'R3', 'R4'], dtype='object')


In [21]: df.columns # column labels

Out[21]: Index(['C1', 'C2', 'C3'], dtype='object')

 

 

 

 

df_2 = DataFrame(df_1, index=['xx', 'xx'], columns=['xx', 'xx']) 형식처럼 기존 df_1에서 행과 열을 선별해서 df_2라는 새로운 DataFrame을 만들 수 있습니다.

 

 

In [22]: df_R1R3 = DataFrame(df, index=['R1', 'R3'])


In [23]: df_R1R3

Out[23]:

     C1   C2    C3
R1  0.0  4.0   8.0
R3  2.0  6.0  10.0


In [24]: df_C1C3 = DataFrame(df, columns=['C1', 'C3'])


In [25]: df_C1C3

Out[25]:

     C1    C3
R1  0.0   8.0
R2  1.0   9.0
R3  2.0  10.0
R4  3.0   NaN


In [26]: df_R3R1_C3C1 = DataFrame(df, index=['R3', 'R1'], columns=['C3', 'C1'])


In [27]: df_R3R1_C3C1

Out[27]:

      C3   C1
R3  10.0  2.0
R1   8.0  0.0

 

 

 

 

DataFrame에서 칼럼 이름을 지정해서 선별하는 방법은 아래 예시 처럼 df[['xx', 'xx']] 처럼 하면 됩니다.

 

 

# selecting columns from DataFrame

In [28]: df

Out[28]:

     C1   C2    C3
R1  0.0  4.0   8.0
R2  1.0  5.0   9.0
R3  2.0  6.0  10.0
R4  3.0  7.0   NaN


In [29]: df[['C1', 'C2']]

Out[29]:

     C1   C2
R1  0.0  4.0
R2  1.0  5.0
R3  2.0  6.0
R4  3.0  7.0

 

 

 

 

DataFrame에 새로운 칼럼을 만들기때 (1) df['new_column'] = ... 과 (2) df.assign(new_column = ... ) 의 두가지 방법이 있습니다.

 

 

# (1) making a new column

In [30]: df['C4'] = df['C1'] + df['C2']


In [31]: df

Out[31]:

     C1   C2    C3    C4
R1  0.0  4.0   8.0   4.0
R2  1.0  5.0   9.0   6.0
R3  2.0  6.0  10.0   8.0
R4  3.0  7.0   NaN  10.0

 

 

# (2-1) assign() method

In [32]: df = df.assign(C5 = df['C1']*df['C2'])


In [33]: df

Out[33]:

     C1   C2    C3    C4    C5
R1  0.0  4.0   8.0   4.0   0.0
R2  1.0  5.0   9.0   6.0   5.0
R3  2.0  6.0  10.0   8.0  12.0
R4  3.0  7.0   NaN  10.0  21.0

 

# (2-2) the same with the above

In [34]: df.assign(C5 = lambda x: x.C1*x.C2)

Out[34]:

     C1   C2    C3    C4    C5
R1  0.0  4.0   8.0   4.0   0.0
R2  1.0  5.0   9.0   6.0   5.0
R3  2.0  6.0  10.0   8.0  12.0
R4  3.0  7.0   NaN  10.0  21.0

 

 

 

 

DataFrame의 칼럼을 삭제하는 방법에는 (1) df.drop(['xx', 'xx'], 1) 과 (2) del df['xx'] 의 방법이 있습니다.  del df['xx']은 원본 데이터프레임에서 칼럼을 삭제합니다.

 

 

# drop 'C3' column : DataFrame.drop('Column', 1)

In [35]: df_drop_C4C5 = df.drop(['C4', 'C5'], 1)


In [36]: df_drop_C4C5

Out[36]:

     C1   C2    C3
R1  0.0  4.0   8.0
R2  1.0  5.0   9.0
R3  2.0  6.0  10.0
R4  3.0  7.0   NaN

 

 

# delete a column from original DataFrame : del DataFrame['column']

In [37]: df

Out[37]:

     C1   C2    C3    C4    C5
R1  0.0  4.0   8.0   4.0   0.0
R2  1.0  5.0   9.0   6.0   5.0
R3  2.0  6.0  10.0   8.0  12.0
R4  3.0  7.0   NaN  10.0  21.0

 

In [38]: del df['C4']  # delete 'C4' column from the original DataFrame df directly


In [39]: del df['C5']  # delete 'C5' column from the original DataFrame df directly


In [40]: df

Out[40]:

     C1   C2    C3
R1  0.0  4.0   8.0
R2  1.0  5.0   9.0
R3  2.0  6.0  10.0
R4  3.0  7.0   NaN

 

 

 

 

DataFrame의 행(row)과 열(column)을 선택할 때는 df.['xx'][0:2] 를 예를 들어 소개합니다.

 

 

In [42]: df

Out[42]:

     C1   C2    C3
R1  0.0  4.0   8.0
R2  1.0  5.0   9.0
R3  2.0  6.0  10.0
R4  3.0  7.0   NaN

 


# selecting column form DataFrame

In [43]: df['C1']

Out[43]:

R1    0.0
R2    1.0
R3    2.0
R4    3.0
Name: C1, dtype: float64


In [44]: df.C1

Out[44]:

R1    0.0
R2    1.0
R3    2.0
R4    3.0
Name: C1, dtype: float64

 

# selecting row from DataFrame

In [45]: df[0:2]

Out[45]:

     C1   C2   C3
R1  0.0  4.0  8.0
R2  1.0  5.0  9.0

 

# indexing 'column' and 'row' from DataFrame

In [46]: df['C1'][0:2]

Out[46]:

R1    0.0
R2    1.0
Name: C1, dtype: float64


In [47]: df.C1[0:2]

Out[47]:

R1    0.0
R2    1.0
Name: C1, dtype: float64

 

 

 

 

index label을 가지고 행(row) 선택할 때는 df.loc['xx'] 를 사용합니다.

 

 

# Select row by label : df.loc[label]

In [48]: df.loc['R1']

Out[48]:

C1    0.0
C2    4.0
C3    8.0
Name: R1, dtype: float64


In [49]: df.loc[['R1', 'R2']]

Out[49]:

     C1   C2   C3
R1  0.0  4.0  8.0
R2  1.0  5.0  9.0

 

 

 

 

index의 label 이 아니라 정수(integer)로 indexing을 하려면 df.iloc[int] 를 사용해야 합니다.  만약 df.loc[int]를 사용하면 TypeError 가 발생합니다.

 

 

# TypeError: cannot do label indexing on with these indexers [0] of <class 'int'>

In [50]: df.loc[0] # TypeError

TypeError: cannot do label indexing on <class 'pandas.indexes.base.Index'> with these indexers [0] of <class 'int'>

 

 

# Select row by interger location : df.iloc[loc]

In [51]: df.iloc[0]

Out[51]:

C1    0.0
C2    4.0
C3    8.0
Name: R1, dtype: float64


In [52]: df.iloc[0:2]

Out[52]:

     C1   C2   C3
R1  0.0  4.0  8.0
R2  1.0  5.0  9.0

 

 

 

 

DataFrame의 행(row) indexing할 때 df[0:2] 처럼 행의 범위를 ':'로 설정해주어도 됩니다.  df[0] 처럼 정수값을 지정하면 KeyError 납니다(이때는 df.iloc[0] 을 써야 함).

 

 

# KeyError: 0

In [53]: df[0]  # KeyError: 0

KeyError: 0

 

 

# Select rows : df[0:2]

In [54]: df[0:2]

Out[54]:

     C1   C2   C3
R1  0.0  4.0  8.0
R2  1.0  5.0  9.0

 

 

 

 

조건을 부여해서 열을 선택할 수도 있습니다.

 

 

# Select rows by boolean vector : df[bool_vec]

In [55]: df[df['C1'] <= 1.0]

Out[55]:

     C1   C2   C3
R1  0.0  4.0  8.0
R2  1.0  5.0  9.0

 

 

 

 

 

선택할 칼럼을 벡터 객체로 만들어 놓고, DataFrame에서 벡터 객체에 들어있는 칼럼만 선별해올 수도 있겠지요. 분석 프로세스를 자동화하려고 할 때 선행 분석 결과를 받아서 벡터 객체로 만들어 놓고, 이를 받아서 필요한 변수만 선별할 때 종종 사용하곤 합니다.

 


# Select columns by column vector : df[col_bool_vec]

In [56]: df_col_selector = ['C1', 'C2']


In [57]: df[df_col_selector]

Out[57]:

     C1   C2
R1  0.0  4.0
R2  1.0  5.0
R3  2.0  6.0
R4  3.0  7.0

 

 

 

많은 도움 되었기를 바랍니다.

 

 

 

 

 

 

 

 

728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 데이터 프레임, 튜플, 리스트를 특정한 기준에 따라서 정렬, 재배치하는 방법에 대해서 알아보겠습니다.

 

오름차순 혹은 내림차순으로 정렬을 한 후에 상위 n개 (or 하위 n개), 혹은 첫번째 행 (or 마지막 행) 을 선택해야할 필요가 있을 때 사용할 수 있는 method, function 입니다.

 

DataFrame, Tuple, List 정렬 순서대로 소개하겠습니다.

 

 - (1) DataFrame 정렬 : DataFrame.sort_values()

 

 - (2) Tuple 정렬 : sorted(tuple, key)

 

 - (3) List 정렬 : list.sort(), sorted(list)

 

* 참고: Numpy 배열 정렬 np.sort()http://rfriend.tistory.com/357

 

 

 

 

  (1) DataFrame 정렬 : DataFrame.sort_values()

 

먼저 필요한 모듈을 불러오고, 예제 DataFrame을 만들어보겠습니다.

 

 

In [1]: import pandas as pd


In [2]: personnel_df = pd.DataFrame({'sequence': [1, 3, 2],

   ...: 'name': ['park', 'lee', 'choi'],

   ...: 'age': [30, 20, 40]})


In [3]: personnel_df

Out[3]:

   age  name  sequence
0   30  park         1
1   20   lee         3
2   40  choi         2

 

 

 

 

(1-1) 'sequence' 열(by='sequence')을 기준으로 index(axis=0) 오름차순 정렬하기

 

 

# sorting index of DataFrame by a specific column : axis=0, columns

In [4]: personnel_df.sort_values(by=['sequence'], axis=0)

Out[4]:

   age  name  sequence
0
   30  park         1
2   40  choi         2
1
   20   lee          3

 

 

 

 

(1-2) 내림차순(descending)으로 정렬하기 : ascending=False

 

 

# sorting index of dataFrame in descending order : ascending=False

In [5]: personnel_df.sort_values(by=['sequence'], axis=0, ascending=False)

Out[5]:

   age  name  sequence
1   20   lee         3
2   40  choi         2
0   30  park         1

 

 

 

 

(1-3) 열 이름을 (알파벳 순서로) 정렬하기 :  axis=1

 

 

# sorting columns of DataFrame : axis=1

In [6]: personnel_df.sort(axis=1)

Out[6]:

   age  name  sequence
0   30  park         1
1   20   lee         3
2   40  choi         2

 

# sorting columns of DataFrame in descending order : axis=1, ascending=False

In [7]: personnel_df.sort(axis=1, ascending=False

Out[7]:

   sequence  name  age
0         1  park   30
1         3   lee   20
2         2  choi   40

 

 

 

 

(1-4) DataFrame 자체 내에서 정렬된 상태로 다시 저장하기 : inplace=True

 

 

In [8]: personnel_df

Out[8]:

age name sequence

0 30 park 1

1 20 lee 3

2 40 choi 2


# sorting DataFarme in-place : inplace=True

In [9]: personnel_df.sort_values(by=['sequence'], axis=0, inplace=True)


In [10]: personnel_df

Out[10]:

age name sequence

0 30 park 1

2 40 choi 2

1 20 lee 3

 

 

 

 

(1-5) 결측값을 처음에(na_position='first'), 혹은 마지막(na_position='last') 위치에 정렬하기

 

 

# putting NaN to DataFrame

In [11]: import numpy as np


In [12]: personnel_df = pd.DataFrame({'sequence': [1, 3, np.nan],

    ...: 'name': ['park', 'lee', 'choi'],

    ...: 'age': [30, 20, 40]})

    ...:


In [13]: personnel_df

Out[13]:

   age  name  sequence
0   30  park       1.0
1   20   lee       3.0
2   40  choi       NaN

 


# first puts NaNs at the beginning : na_position='first'

In [14]: personnel_df.sort_values(by=['sequence'], axis=0, na_position='first')

Out[14]:

   age  name  sequence
2   40  choi       NaN
0   30  park       1.0
1   20   lee       3.0

 


# last puts NaNs at the end : na_position='last'

In [15]: personnel_df.sort_values(by=['sequence'], axis=0, na_position='last')

Out[15]:

   age  name  sequence
0   30  park       1.0
1   20   lee       3.0
2   40  choi       NaN

 

 

 

 

  (2) Tuple 정렬하기 : sorted(tuple, key) method

 

 

# making a tuple

In [16]: personnel_tuple = [(1, 'park', 30),

    ...: (3, 'lee', 20),

    ...: (2, 'choi', 40)]


In [17]: personnel_tuple

Out[17]: [(1, 'park', 30), (3, 'lee', 20), (2, 'choi', 40)]

 


# use 'key' parameter to specify a function to be called on

# sort by sequence number

In [18]: sorted(personnel_tuple, key=lambda personnel: personnel[0])

Out[18]: [(1, 'park', 30), (2, 'choi', 40), (3, 'lee', 20)]


# sort by name

In [19]: sorted(personnel_tuple, key=lambda personnel: personnel[1])

Out[19]: [(2, 'choi', 40), (3, 'lee', 20), (1, 'park', 30)]

 

# sort by age

In [20]: sorted(personnel_tuple, key=lambda personnel: personnel[2])

Out[20]: [(3, 'lee', 20), (1, 'park', 30), (2, 'choi', 40)]

 

 

 

내림차순(descending order)으로 정렬하고 싶으면 'reverse=True' 옵션을 설정해주면 됩니다.

 

 

# sorting tuple in descending order by age : reverse=True

In [21]: sorted(personnel_tuple, reverse=True, key=lambda personnel: personnel[2])

Out[21]: [(2, 'choi', 40), (1, 'park', 30), (3, 'lee', 20)]

 

 

 

 

  (3) List 정렬하기 : sorted(list), or list.sort()

 

 

 

# making a list

In [23]: my_list = [0, 1, 2, 3, 4, 9, 8, 7, 6, 5]

 


# (1) sorting a list : sort(list) function

In [24]: sorted(my_list)

Out[24]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

 

 

# (2) sorting a list : list.sort() method

In [25]: my_list.sort()


In [26]: my_list

Out[26]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

 


# sorting a list in descending order : reverse=True

In [27]: sorted(my_list, reverse=True)

Out[27]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]


In [28]: my_list.sort(reverse=True)


In [29]: my_list

Out[29]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

 

 

 

 

많은 도움 되었기를 바랍니다.

 

 

728x90
반응형
Posted by Rfriend
,

분석을 하다 보면 원본 데이터의 구조가 분석 기법에 맞지 않아서 행과 열의 위치를 바꾼다거나, 특정 요인에 따라 집계를 해서 구조를 바꿔주어야 하는 경우가 있습니다.

 

재구조화(reshaping data)를 위해 사용할 수 있는 Python pandas의 함수들로 아래와 같이 다양한 함수가 있습니다. 

 

 - (1) pivot(), pd.pivot_table()

 - (2) stack(), unstack()

 - (3) melt()

 - (4) wide_to_long()

 - (5) pd.crosstab() 

 

 

이번 포스팅에서는 마지막으로 범주형 변수로 되어있는 요인(factors)별로 교차분석(cross tabulations) 해서, 행, 열 요인 기준 별로 빈도를 세어서 도수분포표(frequency table), 교차표(contingency table) 를 만들어주는 pd.crosstab() 에 대해서 알아보겠습니다.

 

 

 

 

 

먼저 필요한 모듈을 불러오고, 예제로 사용할 (범주형 요인 변수를 가지고 있는) 간단한 데이터셋을 생성해보겠습니다.

 

 

In [1]: import pandas as pd


In [2]: from pandas import DataFrame


In [3]: data = DataFrame({'id': ['id1', 'id1', 'id1', 'id2', 'id2', 'id3'],

   ...: 'fac_1': ['a', 'a', 'a', 'b', 'b', 'b'],

   ...: 'fac_2': ['d', 'd', 'd', 'c', 'c', 'd']})


In [4]: data

Out[4]:

    fac_1   fac_2    id
0     a       d       id1
1     a       d       id1
2     a       d       id1
3     b       c       id2
4     b       c       id2
5     b       d       id3

 

 

 

 

  (1) 교차표(contingency table, frequency table) 만들기 : pd.crosstab(index, columns)

 

pd.crosstab()의 행과 열 위치에는 array 형식의 데이터가 들어갑니다

 

 

# cross tabulations using pd.crosstab => contingency table

In [5]: pd.crosstab(data.fac_1, data.fac_2)

Out[5]:
fac_2  c  d
fac_1     
a      0  3
b      2  1

 

In [6]: pd.crosstab(data.id, data.fac_1)

Out[6]: 
fac_1  a  b
id        
id1    3  0
id2    0  2
id3    0  1

 

In [7]: pd.crosstab(data.id, data.fac_2)

Out[7]:
fac_2  c  d
id        
id1    0  3
id2    2  0
id3    0  1

 

 

 

 

  (2) Multi-index, Multi-level로 교차표 만들기 : pd.crosstab([id1, id2], [col1, col2])

 

 

# cross tabulations using pd.crosstab with Multi-level columns

In [8]: pd.crosstab(data.id, [data.fac_1, data.fac_2])

Out[8]:

fac_1  a  b  
fac_2  d  c  d
id           
id1    3  0  0
id2    0  2  0
id3    0  0  1


In [9]: pd.crosstab([data.fac_1, data.fac_2], data.id)

Out[9]:

id           id1  id2  id3
fac_1 fac_2              
a     d        3    0    0
b     c        0    2    0
      d        0    0    1

 

 

 

 

  (3) 교차표의 행 이름, 열 이름 부여 : pd.crosstab(rownames=['xx'], colnames=['aa'])

 

 

# pd.crosstab(rownames, colnames) : giving rownames, colnames

In [10]: pd.crosstab(data.id, [data.fac_1, data.fac_2],

    ...: rownames=['id_num'],

    ...: colnames=['a_b', 'c_d'])

Out[10]:

a_b     a  b  
c_d     d  c  d
id_num        
id1     3  0  0
id2     0  2  0
id3     0  0  1

 

 

 

 

  (4) 교차표의 행 합, 열 합 추가하기 : pd.crosstab(margins=True)

 

 

# pd.crosstab(margins=True) : adding row/column margins

In [11]: pd.crosstab(data.id, [data.fac_1, data.fac_2],

    ...: margins=True)

Out[11]:

fac_1  a  b    All
fac_2  d  c  d   
id               
id1    3  0  0   3
id2    0  2  0   2
id3    0  0  1   1
All    3  2  1   6

 

 

 

 

 

  (5) 구성비율로 교차표 만들기 : pd.crosstab(normalize=True)

 

# pd.corsstab(normalize=True)
# : Normalize by dividing all values by the sum of values

In [12]: pd.crosstab(data.id, [data.fac_1, data.fac_2],

    ...: normalize=True)

Out[12]:

fac_1    a         b         
fac_2    d         c         d
id                           
id1    0.5  0.000000  0.000000
id2    0.0  0.333333  0.000000
id3    0.0  0.000000  0.166667

 

 

 

 

이상으로 pd.crosstab() 을 이용한 교차표 구하기를 마치겠습니다. 

 

 

교차표는 R이나 SPSS가 깔끔하게 결과를 제시해주는 것 같고요, R이 분석가가 설정할 수 있는 옵션이 조금 더 다양하므로 입맛에 맞게 교차분석도 하고 카이제곱검정도 하고 싶은 분은 아래 링크되어 있는 포스팅을 참고하세요. 

 

 

 

많은 도움이 되었기를 바랍니다.  

 

 

728x90
반응형
Posted by Rfriend
,

분석을 하다 보면 원본 데이터의 구조가 분석 기법에 맞지 않아서 행과 열의 위치를 바꾼다거나, 특정 요인에 따라 집계를 해서 구조를 바꿔주어야 하는 경우가 있습니다.

 

재구조화(reshaping data)를 위해 사용할 수 있는 Python pandas의 함수들에 대해서 아래의 순서대로 나누어서 소개해보겠습니다.

 

 - (1) pivot(), pd.pivot_table()

 - (2) stack(), unstack()

 - (3) melt()

 - (4) wide_to_long()

 - (5) pd.crosstab() 

 

 

이번 포스팅에서는 pd.wide_to_long() 에 대해서 알아보겠습니다.

 

필요한 모듈을 불러오고, 실습에 필요한 간단한 예제 데이터셋을 만들어보겠습니다.

 

 

# importing libraries

In [1]: import numpy as np


In [2]: import pandas as pd


In [3]: from pandas import DataFrame


# setting random seed number

In [4]: np.random.seed(10)


# making an example 'wide' DataFrame

In [5]: data_wide = pd.DataFrame({"C1prd1" : {0 : "a", 1 : "b", 2 : "c"},

   ...: "C1prd2" : {0 : "d", 1 : "e", 2 : "f"},

   ...: "C2prd1" : {0 : 2.5, 1 : 1.2, 2 : .7},

   ...: "C2prd2" : {0 : 3.2, 1 : 1.3, 2 : .1},

   ...: "value" : dict(zip(range(3), np.random.randn(3)))

   ...: })

   ...:


In [6]: data_wide["seq_no"] = data_wide.index


In [7]: data_wide

Out[7]:

     C1prd1 C1prd2  C2prd1  C2prd2     value      seq_no
0       a         d         2.5       3.2      1.331587       0
1       b         e         1.2       1.3      0.715279       1
2       c          f         0.7       0.1     -1.545400       2

 

 

 

 

이제 pd.wide_to_long() 함수를 써서 데이터를 재구조화 해보겠습니다.

 

wide_to_long()은 pivot() 이나 stack() 과는 다르게 "칼럼 이름의 앞부분"과 나머지 "칼럼 이름의 뒷부분"을 구분해서, 칼럼 이름의 앞부분을 칼럼 이름으로, 칼럼 이름의 나머지 뒷부분을 행(row)의 원소로 해서 세로로 길게(long~) 쌓아 줍니다.  말로 설명해주기가 참 힘든데요, 아래의 wide_to_long() 적용 전, 후의 변화 이미지를 참고하시기 바랍니다.

 

제가 R, SAS, SPSS 다 써봤는데요, Python의 pd.wide_to_long() 함수 같은거는 본 적이 없습니다. 좀 생소하고, 처음 봤을 때 한눈에 잘 안들어왔던 유형의 데이터 재구조화 함수예요. 

 

 

 

pd.widt_to_long() 함수를 한번 사용해서 가로로 넓은 데이터(wide~)를 세로로 길게(long~) 재구조화 해보겠습니다.

 

 

  (1) pd.wide_to_long(data, ["col_prefix_1", "col_prefix_2"], i="idx_1", j="idx_2")

 

 

# reshaping a 'wide' DataFrame to a 'long' DataFrame

In [8]: data_long = pd.wide_to_long(data_wide, ["C1", "C2"], i="seq_no", j="prd")


In [9]: data_long

Out[9]:

                     value    C1    C2
seq_no prd                 
0        prd1  1.331587      2.5
1        prd1  0.715279   b     1.2
2        prd1 -1.545400   c     0.7
0        prd2  1.331587      3.2
1        prd2  0.715279   e     1.3
2        prd2 -1.545400   f     0.1

 

 

 

 

  (2) pd.wide_to_long()에 의한 index, columns 변화 비교

 

 

# data_wide (original data set) : index, columns

In [10]: data_wide.index

Out[10]: Int64Index([0, 1, 2], dtype='int64')


In [11]: data_wide.columns

Out[11]: Index(['C1prd1', 'C1prd2', 'C2prd1', 'C2prd2', 'value', 'seq_no'], dtype='object')

 


# data_long (reshaped data set) : index, columns

In [12]: data_long.index

Out[12]:

MultiIndex(levels=[[0, 1, 2], ['prd1', 'prd2']],

labels=[[0, 1, 2, 0, 1, 2], [0, 0, 0, 1, 1, 1]],

names=['seq_no', 'type'])


In [13]: data_long.columns

Out[13]: Index(['value', 'C1', 'C2'], dtype='object')

 

 

 

이상으로 pd.wide_to_long() 을 이용한 데이터 재구조화 소개를 마치겠습니다.

 

다음번 포스팅에서는 pd.crosstab() 에 대해서 알아보겠습니다.

 

많은 도움 되었기를 바랍니다.

 

 

728x90
반응형
Posted by Rfriend
,

데이터 재구조화(reshaping data)를 위해 사용할 수 있는 Python pandas의 함수들에 대해서 아래의 순서대로 나누어서 소개해보겠습니다.
 
 - (1) pivot(), pd.pivot_table()
 - (2) stack(), unstack()
 - (3) melt()

 - (4) wide_to_long()
 - (5) pd.crosstab() 
 
 
이번 포스팅에서는 세번째로 pd.melt() 사용법에 대해서 알아보겠습니다.

 

R 사용자라면 reshape package의 melt(), cast() 함수를 생각하면 쉽게 이해할 수 있을 것입니다. melt()는 pivot_table()과 함께 데이터 전처리 단계에서 자주 사용되곤 합니다.

 

melt() 는 ID 변수를 기준으로 원래 데이터셋에 있던 여러개의 칼럼 이름을 'variable' 칼럼에 위에서 아래로 길게 쌓아놓고, 'value' 칼럼에 ID와 variable에 해당하는 값을 넣어주는 식으로 데이터를 재구조화합니다.  말로 설명하자니 좀 어려운데요, 아래의 melt() 적용 전, 후의 이미지를 참고하시기 바랍니다.

 

 

 

 

필요한 라이브러리를 불러오고, 예제로 사용할 간단한 DataFrame을 만들어보겠습니다.

 

 

# importing libraries

In [1]: import numpy as np


In [2]: import pandas as pd


In [3]: from pandas import DataFrame

 

# making an example DataFrame

In [4]: data = DataFrame({'cust_ID' : ['C_001', 'C_001', 'C_002', 'C_002'],

   ...: 'prd_CD' : ['P_001', 'P_002', 'P_001', 'P_002'],

   ...: 'pch_cnt' : [1, 2, 3, 4],

   ...: 'pch_amt' : [100, 200, 300, 400]})

   ...:


In [5]: data

Out[5]:

  cust_ID  pch_amt  pch_cnt prd_CD
0   C_001      100        1  P_001
1   C_001      200        2  P_002
2   C_002      300        3  P_001
3   C_002      400        4  P_002

 

 

 

 

  (1) pd.melt(data, id_vars=['id1', 'id2', ...]) 를 사용한 데이터 재구조화

 

 

# melt()

In [6]: pd.melt(data, id_vars=['cust_ID', 'prd_CD'])

Out[6]:

   cust_ID prd_CD variable     value
0   C_001  P_001  pch_amt    100
1   C_001  P_002  pch_amt    200
2   C_002  P_001  pch_amt    300
3   C_002  P_002  pch_amt    400
4   C_001  P_001  pch_cnt      1
5   C_001  P_002  pch_cnt      2
6   C_002  P_001  pch_cnt      3
7   C_002  P_002  pch_cnt      4

 

 

 

 (2) pd.melt() 의 variable 이름, value 이름 부여하기 : var_name, value_name

 

 

# # melt : assigning name of variable and value

In [7]: pd.melt(data, id_vars=['cust_ID', 'prd_CD'],

   ...: var_name='pch_CD', value_name='pch_value')

Out[7]:

  cust_ID  prd_CD  pch_CD      pch_value
0   C_001  P_001   pch_amt        100
1   C_001  P_002   pch_amt        200
2   C_002  P_001   pch_amt        300
3   C_002  P_002   pch_amt        400
4   C_001  P_001   pch_cnt          1
5   C_001  P_002   pch_cnt          2
6   C_002  P_001   pch_cnt          3
7   C_002  P_002   pch_cnt          4

 

 

 

 

  (3) data vs. pd.melt() vs. pd.pivot_table() 비교해보기

 

melt()와 pivot_table() 이 비슷한거 같은데.... 뭔가 다른거 같기도 하고... 왜 비슷한것들을 여러개 만들어놔서 사람을 헷갈리게 하는 것일까 의아할 것 같습니다.

 

아래에 똑같은 data에 대해서 melt()와 pivot_table() 을 적용해보았습니다.  melt()와 pivot_table()을 적용하고 난 이후의 index와 columns 을 유심히 살펴보시기 바랍니다.  melt()는 ID가 칼럼으로 존재하는 반면에, pivot_table()은 ID가 index로 들어갔습니다.

 

 

# comparison among (a) data vs. (b) pd.melt() vs. pd.pivot_table()

 

# (a) data

In [8]: data

Out[8]:

  cust_ID  pch_amt  pch_cnt prd_CD
0   C_001      100        1  P_001
1   C_001      200        2  P_002
2   C_002      300        3  P_001
3   C_002      400        4  P_002

 


# (b) melt()

In [9]: data_melt = pd.melt(data, id_vars=['cust_ID', 'prd_CD'],

   ...: var_name='pch_CD', value_name='pch_value')


In [10]: data_melt

Out[10]:

  cust_ID prd_CD   pch_CD  pch_value
0   C_001  P_001  pch_amt        100
1   C_001  P_002  pch_amt        200
2   C_002  P_001  pch_amt        300
3   C_002  P_002  pch_amt        400
4   C_001  P_001  pch_cnt          1
5   C_001  P_002  pch_cnt          2
6   C_002  P_001  pch_cnt          3
7   C_002  P_002  pch_cnt          4


In [11]: data_melt.index

Out[11]: RangeIndex(start=0, stop=8, step=1)


In [12]: data_melt.columns

Out[12]: Index(['cust_ID', 'prd_CD', 'pch_CD', 'pch_value'], dtype='object')

 


# (c) pd.pivot_table()

In [13]: data_melt_pivot = pd.pivot_table(data_melt, index=['cust_ID', 'prd_CD'],

    ...: columns='pch_CD', values='pch_value',

    ...: aggfunc=np.mean)


In [14]: data_melt_pivot

Out[14]:

pch_CD             pch_amt   pch_cnt
cust_ID prd_CD                 
C_001   P_001       100        1
           P_002       200        2
C_002   P_001       300        3
           P_002       400        4


In [15]: data_melt_pivot.index

Out[15]:

MultiIndex(levels=[['C_001', 'C_002'], ['P_001', 'P_002']],

labels=[[0, 0, 1, 1], [0, 1, 0, 1]],

names=['cust_ID', 'prd_CD'])


In [16]: data_melt_pivot.columns

Out[16]: Index(['pch_amt', 'pch_cnt'], dtype='object', name='pch_CD')

 

 

 

이상으로 Pytho pandas의 melt() 함수를 가지고 데이터 재구조화하는 방법에 대한 소개를 마치겠습니다.

 

다음번 포스팅에서는 wide_to_long() 함수에 대해서 알아보겠습니다.

 

 

 

728x90
반응형
Posted by Rfriend
,

데이터 재구조화(reshaping data)를 위해 사용할 수 있는 Python pandas의 함수들에 대해서 아래의 순서대로 나누어서 소개해보겠습니다.

 

 - (1) pivot(), pd.pivot_table()

 - (2) stack(), unstack()

 - (3) melt()

 - (4) wide_to_long()

 - (4) pd.crosstab() 

 

 

이번 포스팅에서는 두번째로 pd.DataFrame.stack(), pd.DataFrame.unstack()에 대해서 알아보겠습니다.

 


 

stack을 영어사전에서 찾아보면 뜻이

stack[stӕk]

~ (sth) (up) (깔끔하게 정돈하여) 쌓다[포개다]; 쌓이다, 포개지다
~ sth (with sth) (어떤 곳에 물건을 쌓아서) 채우다

 

라는 뜻입니다.

 

stack이 (위에서 아래로 길게, 높게) 쌓는 것이면, unstack은 쌓은 것을 옆으로 늘어놓는것(왼쪽에서 오른쪽으로 넓게) 라고 연상이 될 것입니다.

 

Python pandas의 stack(), unstack() 실습에 필요한 모듈을 불러오고, 예제로 사용할 hierarchical index를 가진 DataFrame을 만들어보겠습니다.  

 

 

 

In [1]: import numpy as np


In [2]: import pandas as pd


In [3]: from pandas import DataFrame


In [4]: mul_index = pd.MultiIndex.from_tuples([('cust_1', '2015'), ('cust_1', '2016'),

   ...: ('cust_2', '2015'), ('cust_2', '2016')])

   ...:


In [5]: data = DataFrame(data=np.arange(16).reshape(4, 4),

   ...: index=mul_index,

   ...: columns=['prd_1', 'prd_2', 'prd_3', 'prd_4'],

   ...: dtype='int')

   ...:


In [6]: data

Out[6]:

                 prd_1  prd_2  prd_3  prd_4
cust_1 2015      0       1      2      3
         2016      4       5      6      7
cust_2 2015      8       9     10     11
         2016     12     13     14     15


 

 

 

 

 

stack() method 를 사용해서 위의 예제 데이터셋을 위에서 아래로 길게(높게) 쌓아(stack) 보겠습니다.  칼럼의 level은 1개 밖에 없으므로 stack(level=-1) 을 별도로 명기하지 않아도 됩니다.

 

 

  (1) pd.DataFrame.stack(level=-1, dropna=True)

 

DataFrame을 stack() 후에 index를 확인해보고, indexing 해보겠습니다.

DataFrame을 stack() 하면 Series 를 반환합니다.

 

 

# stack()

In [7]: data_stacked = data.stack()

 

# DataFrame.stack() => returns Series

In [8]: data_stacked

Out[8]:

cust_1  2015  prd_1     0
                  prd_2     1
                  prd_3     2
                  prd_4     3
          2016  prd_1     4
                  prd_2     5
                  prd_3     6
                  prd_4     7
cust_2  2015  prd_1     8
                  prd_2     9
                  prd_3    10
                  prd_4    11
          2016  prd_1    12
                  prd_2    13
                  prd_3    14
                  prd_4    15

dtype: int32

 


# MultiIndex(levels) after stack()

In [9]: data_stacked.index

Out[9]:

MultiIndex(levels=[['cust_1', 'cust_2'], ['2015', '2016'], ['prd_1', 'prd_2', 'prd_3', 'prd_4']],

labels=[[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1], [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]])

 


# indexing

In [10]: data_stacked['cust_2']['2015'][['prd_1', 'prd_2']]

Out[10]:

prd_1 8

prd_2 9

dtype: int32

 

 

 

 

결측값이 있는 데이터셋을 stack() 할 때 결측값을 제거할지(dropna=True), 아니면 결측값을 NaN으로 유지할지(dropna=False) 설정할 수 있는 stack(dropna=True, False)를 예를 들어 설명해보겠습니다.

 

 

# # putting NaN to DataFrame

In [11]: data.ix['cust_2', 'prd_4'] = np.nan


In [12]: data

Out[12]:

             prd_1  prd_2  prd_3  prd_4
cust_1 2015      0      1      2    3.0
         2016      4      5      6    7.0
cust_2 2015      8      9     10    NaN
         2016     12     13     14    NaN

 


# stack with 'dropna=False' argument

In [13]: data.stack(dropna=False)

Out[13]:

cust_1  2015  prd_1     0.0
                  prd_2     1.0
                  prd_3     2.0
                  prd_4     3.0
          2016  prd_1     4.0
                  prd_2     5.0
                  prd_3     6.0
                  prd_4     7.0
cust_2  2015  prd_1     8.0
                  prd_2     9.0
                  prd_3    10.0
                  prd_4     NaN
          2016  prd_1    12.0
                  prd_2    13.0
                  prd_3    14.0
                  prd_4     NaN

dtype: float64

 


# stack with 'dropna=True' argument

In [14]: data.stack(dropna=True) # by default

Out[14]:

cust_1  2015  prd_1     0.0
                  prd_2     1.0
                  prd_3     2.0
                  prd_4     3.0
          2016  prd_1     4.0
                  prd_2     5.0
                  prd_3     6.0
                  prd_4     7.0
cust_2  2015  prd_1     8.0
                  prd_2     9.0
                  prd_3    10.0
          2016  prd_1    12.0
                  prd_2    13.0
                  prd_3    14.0

dtype: float64

 

 

 

 

 

stack()으로 위에서 아래로 길게(높게) 쌓아 올린 데이터셋을 이번에는 거꾸로 왼쪽으로 오른쪽으로 넓게 unstack()으로 풀어보겠습니다. 

 

stack() 후의 data_stacked 데이터셋이 아래에 보는 것처럼 level이 3개 있는 MultiIndex 입니다. 이럴 경우 unstack(level=-1), unstack(level=0), unstack(level=1) 별로 어떤 level이 칼럼으로 이동해서 unstack() 되는지 유심히 살펴보시기 바랍니다. 

 

  (2) pd.DataFrame.unstack(level=-1, fill_value=None)

 

 

In [15]: data_stacked

Out[15]:

cust_1  2015  prd_1     0
                  prd_2     1
                  prd_3     2
                  prd_4     3
          2016  prd_1     4
                  prd_2     5
                  prd_3     6
                  prd_4     7
cust_2  2015  prd_1     8
                  prd_2     9
                  prd_3    10
                  prd_4    11
          2016  prd_1    12
                  prd_2    13
                  prd_3    14
                  prd_4    15

dtype: int32


In [16]: data_stacked.unstack(level=-1)

Out[16]:

                 prd_1  prd_2  prd_3  prd_4
cust_1 2015      0      1      2      3
         2016      4      5      6      7
cust_2 2015      8      9     10     11
         2016     12     13     14     15


In [17]: data_stacked.unstack(level=0)

Out[17]:

                cust_1  cust_2
2015 prd_1       0       8
       prd_2       1       9
       prd_3       2      10
       prd_4       3      11
2016 prd_1       4      12
       prd_2       5      13
       prd_3       6      14
       prd_4       7      15

 

In [18]: data_stacked.unstack(level=1)

Out[18]:

                  2015  2016
cust_1 prd_1     0     4
         prd_2     1     5
         prd_3     2     6
         prd_4     3     7
cust_2 prd_1     8    12
         prd_2     9    13
         prd_3    10    14
         prd_4    11    15

 

 

 

 

unstack() 한 후의 데이터셋도 역시 Series 인데요, 이것을 DataFrame으로 변환해보겠습니다.

 

 

# converting Series to DataFrame

In [19]: data_stacked_unstacked = data_stacked.unstack(level=-1)


In [20]: data_stacked_unstacked

Out[20]:

                prd_1  prd_2  prd_3  prd_4
cust_1 2015      0      1      2      3
         2016      4      5      6      7
cust_2 2015      8      9     10     11
         2016     12     13     14     15

 

# converting index to columns

In [21]: data_stacked_unstacked_df = data_stacked_unstacked.reset_index()

 

# changing columns' name

In [22]: data_stacked_unstacked_df.rename(columns={'level_0' : 'custID',

    ...: 'level_1' : 'year'}, inplace=True)

    ...:


In [23]: data_stacked_unstacked_df

Out[23]:

    custID  year  prd_1  prd_2  prd_3  prd_4
0  cust_1  2015      0      1      2      3
1  cust_1  2016      4      5      6      7
2  cust_2  2015      8      9     10     11
3  cust_2  2016     12     13     14     15

 

 

 

 

이상으로 stack(), unstack()을 이용한 데이터 재구조화에 대해서 알아보았습니다.  

 

다음번 포스팅에서는 melt(), wide_to_long() 을 이용한 데이터 재구조화를 소개하겠습니다.

 

많은 도움 되었기를 바랍니다.

 

 

728x90
반응형
Posted by Rfriend
,

분석을 하다 보면 원본 데이터의 구조가 분석 기법에 맞지 않아서 행과 열의 위치를 바꾼다거나, 특정 요인에 따라 집계를 해서 구조를 바꿔주어야 하는 경우가 있습니다.

 

이번 포스팅부터는 이처럼 데이터 재구조화(reshaping data)를 위해 사용할 수 있는 Python pandas의 함수들에 대해서 아래의 순서대로 나누어서 소개해보겠습니다.

 

 - (1) pivot(), pd.pivot_table()

 - (2) stack(), unstack()

 - (3) melt()

 - (4) wide_to_long()

 - (5) pd.crosstab() 

 

 

이번 포스팅에서는 첫번째로 data.pivot(), pd.pivot_table(data)에 대해서 알아보겠습니다.

 

 

 

 

먼저, 필요한 모듈을 불러오고, 간단한 예제 데이터셋을 만들어보겠습니다.  고객ID(cust_id), 상품 코드(prod_cd), 등급(grade), 구매금액(pch_amt) 의 4개 변수로 이루어진 데이터 프레임입니다.

 

 

# importing libraries

 

In [1]: import numpy as np


In [2]: import pandas as pd


In [3]: from pandas import DataFrame

 

 

# making an example DataFrame

In [4]: data = DataFrame({'cust_id': ['c1', 'c1', 'c1', 'c2', 'c2', 'c2', 'c3', 'c3', 'c3'],

   ...: 'prod_cd': ['p1', 'p2', 'p3', 'p1', 'p2', 'p3', 'p1', 'p2', 'p3'],

   ...: 'grade' : ['A', 'A', 'A', 'A', 'A', 'A', 'B', 'B', 'B'],

   ...: 'pch_amt': [30, 10, 0, 40, 15, 30, 0, 0, 10]})

   ...:


In [5]: data

Out[5]:

  cust_id grade  pch_amt prod_cd
0      c1     A       30      p1
1      c1     A       10      p2
2      c1     A        0      p3
3      c2     A       40      p1
4      c2     A       15      p2
5      c2     A       30      p3
6      c3     B        0      p1
7      c3     B        0      p2
8      c3     B       10      p3

 

 

 

 

위의 data 예제처럼 위에서 아래로 길게 늘어서 있는 데이터셋을 행(row)에는 고객ID(cust_id), 열(column)에는 상품코드(prd_cd), 행과 열이 교차하는 칸에는 구매금액(pch_amt)이 위치하도록 데이터를 구조를 바꿔보겠습니다.  말로 설명해도 이해가 잘 안될 수 있는데요, 아래 data.pivot(index, columns, values) 예시를 보시지요.

 

 

  (1) 데이터 재구조화 : data.pivot(index, columns, values)

 

 

# reshaping DataFrame by pivoting

 

In [6]: data_pivot = data.pivot(index='cust_id', columns='prod_cd', values='pch_amt')


In [7]: data_pivot

Out[7]:

prod_cd  p1  p2  p3
cust_id           
c1       30  10   0
c2       40  15  30
c3        0   0  10

 

 

 

 

 

  (2) 데이터 재구조화 : pd.pivot_table(data, index, columns, values, aggfunc)

 

위의 data.pivot() 과 동일한 결과가 나오도록 데이터를 재구조화하는데 pd.pivot_table()을 사용할 수도 있습니다.

 

 

# pd.pivot_table(data, index, columns, values, aggfunc)

 

In [8]: pd.pivot_table(data, index='cust_id', columns='prod_cd', values='pch_amt')

Out[8]:

prod_cd  p1  p2  p3
cust_id           
c1       30  10   0
c2       40  15  30
c3        0   0  10

 

 

 

 

data.pivot() 로 하면 에러가 나서 안되고, pivot_table(data) 을 사용해야만 하는 경우가 몇 가지 있습니다.  그러므로 여러가지 외우는거 싫고, 헷갈리는거 싫어하는 분이라면 pivot_table() 사용법만 잘 숙지하는 것도 좋은 방법입니다.

 

아래에 pivot()으로는 안되고 pivot_table()은 되는 경우를 나란히 이어서 제시해보겠습니다.

 

(a) index 가 2개 이상인 경우입니다.

 

 

# pivot() with 2 indices :ValueError

 

In [9]: data.pivot(index=['cust_id', 'grade'], columns='prod_cd', values='pch_amt')

ValueError: Wrong number of items passed 9, placement implies 2

 

 

# pd.pivot_table() with 2 indices : works well!

 

In [10]: pd.pivot_table(data, index=['cust_id', 'grade'], columns='prod_cd', values='pch_amt')

Out[10]:

prod_cd        p1  p2  p3
cust_id grade           
c1      A      30  10   0
c2      A      40  15  30
c3      B       0   0  10

 

 

 

 

(b) columns 가 2개 이상인 경우 입니다.

 

 

# pivot() with 2 columns : KeyError

 

In [11]: data.pivot(index='cust_id', columns=['grade', 'prod_cd'], values='pch_amt')

KeyError: 'Level grade not found'

 

 

# pd.pivot_table() with 2 columns : works well!

 

In [12]: pd.pivot_table(data, index='cust_id', columns=['grade', 'prod_cd'], values='pch_amt')

Out[12]:

grade A B

grade       A                B          
prod_cd    p1    p2    p3   p1   p2    p3
cust_id                                 
c1       30.0  10.0   0.0  NaN  NaN   NaN
c2       40.0  15.0  30.0  NaN  NaN   NaN
c3        NaN   NaN   NaN  0.0  0.0  10.0

 

 

 

 

pivot() 함수는 중복값이 있을 경우 ValueError를 반환합니다.  반면에, pd.pivot_table()은 aggfunc=np.sum 혹은 aggfunc=np.mean 과 같이 집계(aggregation)할 수 있는 함수를 제공함에 따라 index 중복값이 있는 경우에도 문제가 없습니다.

 

 

# pivot() with index which contains duplicate entries: ValueError

In [13]: data.pivot(index='grade', columns='prod_cd', values='pch_amt')

ValueError: Index contains duplicate entries, cannot reshape

 

 

# pd.pivot_table() with aggfunc : works well!

 

In [14]: pd.pivot_table(data, index='grade', columns='prod_cd',

    ...: values='pch_amt', aggfunc=np.sum)

Out[14]:

prod_cd  p1  p2  p3
grade             
A        70  25  30
B         0   0  10

 

In [15]: pd.pivot_table(data, index='grade', columns='prod_cd',

    ...: values='pch_amt', aggfunc=np.mean)

Out[15]:

prod_cd    p1    p2    p3
grade                   
A        35.0  12.5  15.0
B         0.0   0.0  10.0


# pivot_table(aggfunc=np.mean), by default

In [16]: pd.pivot_table(data, index='grade', columns='prod_cd', values='pch_amt')

Out[16]:

prod_cd    p1    p2    p3
grade                   
A        35.0  12.5  15.0
B         0.0   0.0  10.0

 

 

 

 

pd.pivot_table()은 margins=True 옵션을 설정해주면 행과 열을 기준으로 합계(All, row sum, column sum)를 같이 제시해주기 때문에 꽤 편리합니다

 

 

# pd.pivot_table : margins=True
  # special All columns and rows will be added with partial group aggregates
  # across the categories on the rows and columns

 

In [17]: pd.pivot_table(data, index='grade', columns='prod_cd',

    ...: values='pch_amt', aggfunc=np.sum, margins=True)

Out[17]:

prod_cd    p1    p2    p3    All
grade                          
A        70.0  25.0  30.0  125.0
B         0.0   0.0  10.0   10.0
All      70.0  25.0  40.0  135.0

 

In [18]: pd.pivot_table(data, index='grade', columns='prod_cd',

    ...: values='pch_amt', aggfunc=np.mean, margins=True)

Out[18]:

prod_cd         p1         p2         p3        All
grade                                             
A        35.000000  12.500000  15.000000  20.833333
B         0.000000   0.000000  10.000000   3.333333
All      23.333333   8.333333  13.333333  15.000000

 

 

이상으로 data.pivot(), pd.povit_table(data)를 활용한 데이터 재구조화 소개를 마치겠습니다.

 

다음번 포스팅에서는 stack(), unstack()을 이용한 데이터 재구조화에 대해서 알아보겠습니다.

 

많은 도움 되었기를 바랍니다.

 

 

 

728x90
반응형
Posted by Rfriend
,

지난번 포스팅에서는

 

 - Python sklearn.preprocessing.Binarizer()를 이용한 연속형 변수의 이항변수화(binarization)

 

 - Python sklearn.preprocessing.OneHotEncoder()를 이용한 범주형 변수의 이항변수화

 

 - Python np.digitize(), np.where() 를 이용한 연속형 변수의 이산형화(discretization)

 

 

에 대해서 알아보겠습니다.

 

 

이번 포스팅에서는 sklearn.preprocessing.PolynomialFeatures() 를 이용한 다항차수 변환, 교호작용 변수 생성에 대해서 소개하겠습니다.

 

회귀분석할 때 다항 차수를 이용해서 비선형 패턴, 관계(non-linear relation)를 나타내거나, 변수 간 곱을 사용해서 교호작용 효과(interaction effects)을 나타낼 수 있는 변수를 만듭니다.

 

 

 

 

 

 

먼저 필요한 모듈을 불러오고, 예제 Arrary Dataset을 만들어보겠습니다.

 

 

 

In [1]: import numpy as np


In [2]: import pandas as pd


In [3]: from sklearn.preprocessing import PolynomialFeatures


In [4]: X = np.arange(6).reshape(3, 2)


In [5]: X

Out[5]:

array([[0, 1],
       [2, 3],
       [4, 5]])

 

 

 

 

 

  (1) sklearn.preprocessing.PolynomialFeatures()를 사용해 2차항 변수 만들기

 

 

 

# making 2-order polynomial features

 

In [6]: poly = PolynomialFeatures(degree=2)

 

 

# transform from (x1, x2) to (1, x1, x2, x1^2, x1*x2, x2^2)

In [7]: poly.fit_transform(X)

Out[7]:

array([[  1.,   0.,   1.,   0.,   0.,   1.],
       [  1.,   2.,   3.,   4.,   6.,   9.],
       [  1.,   4.,   5.,  16.,  20.,  25.]])

 

 

 

 

변수가 3개인 경우에는 다차항 변수와 교호작용 변수의 조합이 더 많아집니다(아래 예는 degree=2 로서 2차항 변수 & 교호작용 변수 생성 예시)변수가 추가 될 때마다 조합의 경우의 수가 기하급수적으로 늘어나게 되므로 유의할 필요가 있습니다.

 

 

In [8]: X2 = np.arange(9).reshape(3, 3)


In [9]: X2

Out[9]:

array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

 

 

# transform from (x1, x2, x3) to (1, x1, x2, x3, x1^2, x1*x2, x1*x3, x2^2, x2*x3, x3^2)

In [10]: poly.fit_transform(X2)

Out[10]:

array([[  1.,   0.,   1.,   2.,   0.,   0.,   0.,   1.,   2.,   4.],
       [  1.,   3.,   4.,   5.,   9.,  12.,  15.,  16.,  20.,  25.],
       [  1.,   6.,   7.,   8.,  36.,  42.,  48.,  49.,  56.,  64.]])

 

 

 

 

 

  (2) 교호작용 변수만을 만들기 : interaction_only=True

 

다항차수는 적용하지 않고, 오직 호작용 효과만을 분석하려면 interaction_only=True 옵션을 설정해주면 됩니다. degree를 가지고 교호작용을 몇 개 수준까지 볼 지 설정해줄 수 있습니다.

 

 

In [11]: X2

Out[11]:

array([[0, 1, 2],

[3, 4, 5],

[6, 7, 8]])

 

 

# transform from (x1, x2, x3) to (1, x1, x2, x3, x1*x2, x1*x3, x2*x3)

 

In [12]: poly_d2 = PolynomialFeatures(degree=2, interaction_only=True)


In [13]: poly_d2.fit_transform(X2)

Out[13]:

array([[  1.,   0.,   1.,   2.,   0.,   0.,   2.],
       [  1.,   3.,   4.,   5.,  12.,  15.,  20.],
       [  1.,   6.,   7.,   8.,  42.,  48.,  56.]])

 

 

# transform from (x1, x2, x3) to (1, x1, x2, x3, x1*x2, x1*x3, x2*x3, x1*x2*x3)

 

In [14]: poly_d3 = PolynomialFeatures(degree=3, interaction_only=True)

 

In [15]: poly_d3.fit_transform(X2)

Out[15]:

array([[   1.,    0.,    1.,    2.,    0.,    0.,    2.,    0.],
       [   1.,    3.,    4.,    5.,   12.,   15.,   20.,   60.],
       [   1.,    6.,    7.,    8.,   42.,   48.,   56.,  336.]])

 

 

 

 

이상으로 sklearn.preprocessing.PolynomialFeatures()를 이용한 다항차수 변환, 교호작용 변수 생성 방법 소개를 마치겠습니다.

 

 

다음번 포스팅에서는 데이터셋 재구조화(pivot, reshape)에 대해서 알아보겠습니다.

 

 

많은 도움 되었기를 바랍니다.

 

 

 

728x90
반응형
Posted by Rfriend
,

지난번 포스팅에서는

 

 - Python sklearn.preprocessing.Binarizer()를 이용한 연속형 변수의 이항변수화(binarization)

 

 - Python sklearn.preprocessing.OneHotEncoder()를 이용한 범주형 변수의 이항변수화

 

에 대해서 알아보았습니다.

 

 

이번 포스팅에서는 Python np.digitize(), np.where() 를 이용한 연속형 변수의 이산형화(discretization)에 대해서 알아보겠습니다.

 

이항변수화(binarization)는 '0'과 '1'의 값만을 가지는 가변수(dummy variable)를 만드는 것을 의미하며, 이에 비해 이산형화(discretization)은 연속형 변수를 2개 이상의 범주(category)를 가지는 변수로 변환해주는 것을 말합니다.

 

 

 

 

 

먼저, 필요한 모듈을 불러오고, 예제로 사용할 DataFrame을 만들어보겠습니다.

 

#%% discretization of continuous data, binning data

 

# importing modules

In [1]: import numpy as np


In [2]: import pandas as pd


In [3]: from pandas import DataFrame

 

# setting random seed number

In [4]: np.random.seed(10)


# making DataFrame with continuous values

In [5]: df = DataFrame({'C1': np.random.randn(20),

   ...: 'C2': ['a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',

   ...: 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b']})

   ...:


In [6]: df

Out[6]:

           C1   C2
0   1.331587  a
1   0.715279  a
2  -1.545400  a
3  -0.008384  a
4   0.621336  a
5  -0.720086  a
6   0.265512  a
7   0.108549  a
8   0.004291  a
9  -0.174600  a
10  0.433026  b
11  1.203037  b
12 -0.965066  b
13  1.028274  b
14  0.228630  b
15  0.445138  b
16 -1.136602  b
17  0.135137  b
18  1.484537  b
19 -1.079805  b

 

 

 

 

  (1) np.digitize(data, bins)를 이용한 연속형 변수의 이산형화 (discretization)

 

연속형 변수 'C1'을 최소~최대값 구간을 10개 bin으로 균등하게 나누어서 'C1_bin'이라는 이름의 칼럼으로 이산형화 변환해보겠습니다.  ifelse 등의 조건문을 길게 안써도 np.linspace()와 np.dititize() 를 사용해서 아주 간단하게 이산형화 할 수 있습니다.

 

 

# making 10 bins, from min to max of 'C1' column

In [7]: bins = np.linspace(df.C1.min(), df.C1.max(), 10)


In [8]: bins

Out[8]:

array([-1.54540029, -1.20874059, -0.87208089, -0.53542119, -0.19876149,

0.1378982 , 0.4745579 , 0.8112176 , 1.1478773 , 1.484537 ])

 

 

# making digitized column using np.digitize(data, bins)

In [9]: df['C1_bin'] = np.digitize(df['C1'], bins)


In [10]: df

Out[10]:

          C1    C2   C1_bin
0   1.331587  a       9
1   0.715279  a       7
2  -1.545400  a       1
3  -0.008384  a       5
4   0.621336  a       7
5  -0.720086  a       3
6   0.265512  a       6
7   0.108549  a       5
8   0.004291  a       5
9  -0.174600  a       5
10  0.433026  b       6
11  1.203037  b       9
12 -0.965066  b       2
13  1.028274  b       8
14  0.228630  b       6
15  0.445138  b       6
16 -1.136602  b       2
17  0.135137  b       5
18  1.484537  b      10
19 -1.079805  b       2

 

 

 

 

연속형 변수를 이산형화 해서 어디에 써먹나 싶을텐데요, 간단한 예를 들자면 이산형화한 범주(혹은 요인)별로 요약통계량을 집계한다든지, 범주 간 평균 차이나 독립성을 검정한다든지, 분류모형의 목표변수로 사용한다든지, indexing 하는데 사용한다든지 ... 등이 있을 수 있겠네요.

 

 

# aggregation with groupby()

In [11]: df.groupby('C1_bin')['C1'].size()

Out[11]:

C1_bin
1     1
2     3
3     1
5     5
6     4
7     2
8     1
9     2
10    1
dtype: int64

 

# mean by 'C1_bin' groups

In [12]: df.groupby('C1_bin')['C1'].mean()

Out[12]:

C1_bin
1    -1.545400
2    -1.060491
3    -0.720086
5     0.012999
6     0.343076
7     0.668307
8     1.028274
9     1.267312
10    1.484537
Name: C1, dtype: float64

 

# standard deviation by 'C1_bin' groups

In [13]: df.groupby('C1_bin')['C1'].std()

Out[13]:

C1_bin
1          NaN
2     0.087384
3          NaN
5     0.122243
6     0.111985
7     0.066428
8          NaN
9     0.090898
10         NaN
Name: C1, dtype: float64

 

# value counts by 'C1_bin' groups

In [14]: df.groupby('C1_bin')['C2'].value_counts()

Out[14]:

C1_bin  C2
1          a     1
2          b     3
3          a     1
5          a     4
           b     1
6          b     3
           a     1
7          a     2
8          b     1
9          a     1
           b     1
10        b     1
Name: C2, dtype: int64

 

 

# indexing

In [15]: df_bin2 = df[df['C1_bin'] == 2]


In [16]: df_bin2

Out[16]:

          C1 C2  C1_bin
12 -0.965066  b       2
16 -1.136602  b       2
19 -1.079805  b       2

 

 

 

  (2) pd.get_dummies() 를 이용해 가변수(dummy var) 만들기

 

위에서 새로 만든 범주형 변수 'C1_bin'과 pd.get_dummies() 함수를 사용해서 가변수(dummy variable)을 만들어보겠습니다.

 

prefix 옵션을 사용하면 가변수에 공통으로 접두사를 추가할 수 있습니다.

 

drop_first=True 옵션을 설정하면 가변수의 첫번째 변수를 자동으로 삭제를 해주며, 가변수 함정(dummy trap)을 피할 수 있게 해줍니다.

 

 

# get dummy variables with prefix from a categorical variable

 

In [17]: pd.get_dummies(df['C1_bin'], prefix='C1')

Out[17]:

    C1_C1_C1_C1_C1_C1_C1_C1_C1_10
0    0.0   0.0   0.0   0.0   0.0   0.0   0.0   1.0    0.0
1    0.0   0.0   0.0   0.0   0.0   1.0   0.0   0.0    0.0
2    1.0   0.0   0.0   0.0   0.0   0.0   0.0   0.0    0.0
3    0.0   0.0   0.0   1.0   0.0   0.0   0.0   0.0    0.0
4    0.0   0.0   0.0   0.0   0.0   1.0   0.0   0.0    0.0
5    0.0   0.0   1.0   0.0   0.0   0.0   0.0   0.0    0.0
6    0.0   0.0   0.0   0.0   1.0   0.0   0.0   0.0    0.0
7    0.0   0.0   0.0   1.0   0.0   0.0   0.0   0.0    0.0
8    0.0   0.0   0.0   1.0   0.0   0.0   0.0   0.0    0.0
9    0.0   0.0   0.0   1.0   0.0   0.0   0.0   0.0    0.0
10   0.0   0.0   0.0   0.0   1.0   0.0   0.0   0.0    0.0
11   0.0   0.0   0.0   0.0   0.0   0.0   0.0   1.0    0.0
12   0.0   1.0   0.0   0.0   0.0   0.0   0.0   0.0    0.0
13   0.0   0.0   0.0   0.0   0.0   0.0   1.0   0.0    0.0
14   0.0   0.0   0.0   0.0   1.0   0.0   0.0   0.0    0.0
15   0.0   0.0   0.0   0.0   1.0   0.0   0.0   0.0    0.0
16   0.0   1.0   0.0   0.0   0.0   0.0   0.0   0.0    0.0
17   0.0   0.0   0.0   1.0   0.0   0.0   0.0   0.0    0.0
18   0.0   0.0   0.0   0.0   0.0   0.0   0.0   0.0    1.0
19   0.0   1.0   0.0   0.0   0.0   0.0   0.0   0.0    0.0

 

 

# drop_first : Whether to get k-1 dummies out of k categorical levels
#              by removing the first level to avoid dummy trap

In [18]: pd.get_dummies(df['C1_bin'], prefix='C1', drop_first=True)

Out[18]:

    C1_2  C1_3  C1_5  C1_6  C1_7  C1_8  C1_9  C1_10
0    0.0   0.0   0.0   0.0   0.0   0.0   1.0    0.0
1    0.0   0.0   0.0   0.0   1.0   0.0   0.0    0.0
2    0.0   0.0   0.0   0.0   0.0   0.0   0.0    0.0
3    0.0   0.0   1.0   0.0   0.0   0.0   0.0    0.0
4    0.0   0.0   0.0   0.0   1.0   0.0   0.0    0.0
5    0.0   1.0   0.0   0.0   0.0   0.0   0.0    0.0
6    0.0   0.0   0.0   1.0   0.0   0.0   0.0    0.0
7    0.0   0.0   1.0   0.0   0.0   0.0   0.0    0.0
8    0.0   0.0   1.0   0.0   0.0   0.0   0.0    0.0
9    0.0   0.0   1.0   0.0   0.0   0.0   0.0    0.0
10   0.0   0.0   0.0   1.0   0.0   0.0   0.0    0.0
11   0.0   0.0   0.0   0.0   0.0   0.0   1.0    0.0
12   1.0   0.0   0.0   0.0   0.0   0.0   0.0    0.0
13   0.0   0.0   0.0   0.0   0.0   1.0   0.0    0.0
14   0.0   0.0   0.0   1.0   0.0   0.0   0.0    0.0
15   0.0   0.0   0.0   1.0   0.0   0.0   0.0    0.0
16   1.0   0.0   0.0   0.0   0.0   0.0   0.0    0.0
17   0.0   0.0   1.0   0.0   0.0   0.0   0.0    0.0
18   0.0   0.0   0.0   0.0   0.0   0.0   0.0    1.0
19   1.0   0.0   0.0   0.0   0.0   0.0   0.0    0.0

 

 

 

 

  (3) np.where(condition, factor1, factor2, ...)를 이용한 연속형 변수의 이산형화

 

np.where() 를 사용하면 조건절에 좀더 유연하게 조건을 부여해서 이산형화, 범주화를 할 수 있습니다.  연속형 변수 'C1'의 '평균'을 기준으로 평균 이상으로 'high', 평균 미만이면 'low'로 이산형화 변수 'high_low' 신규 변수를 만들어본 후에, 'high_low' 이산형화 변수를 기준으로 요약통계량을 계산해보겠습니다.

 

 

# discretization using np.where(condition, factor1, factor2, ...)

In [17]: df['high_low'] = np.where(df['C1'] >= df.C1.mean(), 'high', 'low')


In [18]: df

Out[18]:

          C1 C2  C1_bin high_low
0   1.331587  a       9     high
1   0.715279  a       7     high
2  -1.545400  a       1      low
3  -0.008384  a       5      low
4   0.621336  a       7     high
5  -0.720086  a       3      low
6   0.265512  a       6     high
7   0.108549  a       5      low
8   0.004291  a       5      low
9  -0.174600  a       5      low
10  0.433026  b       6     high
11  1.203037  b       9     high
12 -0.965066  b       2      low
13  1.028274  b       8     high
14  0.228630  b       6     high
15  0.445138  b       6     high
16 -1.136602  b       2      low
17  0.135137  b       5     high
18  1.484537  b      10     high
19 -1.079805  b       2      low


In [19]: df.groupby('high_low')['C1'].size()

Out[19]:

high_low

high 11

low 9

dtype: int64


In [20]: df.groupby('high_low')['C1'].mean()

Out[20]:

high_low

high 0.717408

low -0.613011

Name: C1, dtype: float64


In [21]: df.groupby('high_low')['C1'].std()

Out[21]:

high_low

high 0.473769

low 0.607895

Name: C1, dtype: float64

 

 

 

 

np.where(condition, ...) 에서 조건절을 조금 더 복잡하게 해서 'Q1(quantile 1, 25%)', 'Q3(quantile 3, 75%) 를 기준으로 '01_high', '02_medium', '03_low' 로 구분해서 이산형화 변환을 해보겠습니다. 

괄호 안에 조건절 주는 부분이 조금 복잡하므로 주의하시기 바랍니다.

 

 

# calculating Q1, Q3

In [22]: Q1 = np.percentile(df['C1'], 25)


In [23]: Q1

Out[23]: -0.31097154812443017


In [24]: Q3 = np.percentile(df['C1'], 75)


In [25]: Q3

Out[25]: 0.64482172401746174

 


# discretizing 3 categories by using np.where() 2 times

In [26]: df['h_m_l'] = np.where(df['C1'] >= Q3, '01_high',

    ...: np.where(df['C1'] >= Q1, '02_medium', '03_low'))

    ...:


In [27]: df

Out[27]:

          C1 C2  C1_bin high_low      h_m_l
0   1.331587  a       9     high      01_high
1   0.715279  a       7     high      01_high
2  -1.545400  a       1      low      03_low
3  -0.008384  a       5      low      02_medium
4   0.621336  a       7     high      02_medium
5  -0.720086  a       3      low      03_low
6   0.265512  a       6     high      02_medium
7   0.108549  a       5      low      02_medium
8   0.004291  a       5      low      02_medium
9  -0.174600  a       5      low      02_medium
10  0.433026  b       6     high     02_medium
11  1.203037  b       9     high     01_high
12 -0.965066  b       2      low     03_low
13  1.028274  b       8     high     01_high
14  0.228630  b       6     high     02_medium
15  0.445138  b       6     high     02_medium
16 -1.136602  b       2      low     03_low
17  0.135137  b       5     high     02_medium
18  1.484537  b      10     high    01_high
19 -1.079805  b       2      low     03_low

 

 

 

 

3개의 범주로 구분해서 새로 만든 'h_m_l' 이산형화 변환 변수를 기준으로 요약통계량을 계산해보면 아래와 같습니다.

 

 

In [28]: df.groupby('h_m_l')['C1'].size()

Out[28]:

h_m_l
01_high       5
02_medium    10
03_low        5

dtype: int64


In [29]: df.groupby('h_m_l')['C1'].mean()

Out[29]:

h_m_l
01_high      1.152543
02_medium    0.205863
03_low      -1.089392

Name: C1, dtype: float64


In [30]: df.groupby('h_m_l')['C1'].std()

Out[30]:

h_m_l
01_high      0.296424
02_medium    0.242969
03_low       0.300877

Name: C1, dtype: float64

 

 

 

이상으로 이산형화(discretization) 변환에 대해서 마치도록 하겠습니다.

 

다음번 포스팅에서는 다항 차수 변환(polynomial variables transformation)에 대해서 알아보겠습니다.

 

많은 도움 되었기를 바랍니다.

 

 

 

728x90
반응형
Posted by Rfriend
,

지난번 포스팅에서는 Python sklearn.preprocessing.Binarizer() 를 사용해서 연속형 변수를 이항변수로 변환하는 방법을 소개하였습니다.

 

이번 포스팅에서는 Python sklearn.preprocessing.OneHotEncoder()를 사용해서 범주형 변수를 이항변수화(binarization of categorical feature) 하는 방법을 알아보겠습니다.

 

가령, 성별(gender)가 '남성(Male)'이면 '0', '여성(Female)'이면 '1'로 encoding 하고,

연령대(age group)가 '20대'이면 '0', '30대'이면 '1', '40대'이면 '2'로 encoding 하고,

등급(grade)가 'S'이면 '0', 'A'이면 '1', 'B'이면 '2', 'C'이면 '3', 'D'이면 '4'로 encoding 한다고 했을 때,

 

이를 value로 '0'과 '1'만을 가진 가변수(dummy variable)로 바꾸는 이항변수화했을 때의 예시가 아래의 이미지입니다.  이것을 Python은 자동으로(auto) 변수별 범주(catogory)의 종류, 개수를 파악해서 이항변수화 해줍니다. 아주 편해요.

 

 

 

 

위의 이미지에 나타난 예제 데이터를 가지고 sklearn.preprocessing.OneHotEncoder() 예를 들어보겠습니다.

 

먼저, 필요한 모듈을 불러오고, 예제 데이터 arrary를 만들어보겠습니다.

 

 

# importing modules

In [1]: from sklearn.preprocessing import OneHotEncoder


In [2]: import numpy as np

 


# making an example data arrary

In [3]: data_train = np.array([[0, 0, 0],

   ...: [0, 1, 1],

   ...: [0, 2, 2],

   ...: [1, 0, 3],

   ...: [1, 1, 4]])

   ...:


In [4]: data_train

Out[4]:

array([[0, 0, 0],
       [0, 1, 1],
       [0, 2, 2],
       [1, 0, 3],
       [1, 1, 4]])

 

 

 

 

  (1) OneHotEncoder() 로 범주형 변수의 이항변수화 적합시키기 : enc.fit()

 

 

# making the utility class OneHotEncoder

In [5]: enc= OneHotEncoder()

 

# fitting OneHotEncoder

In [6]: enc.fit(data_train)

Out[6]:

OneHotEncoder(categorical_features='all', dtype=<class 'float'>,

handle_unknown='error', n_values='auto', sparse=True)

 

 

 

 

  (2) 적합된(fitted) OneHotEncoder()의 Attributes 확인해보기

       : enc.active_features_ , enc.n_values_ , enc.feature_indices_

 

위의 이미지로 예를 들어보였던 범주형 변수의 '변환 이전' => 이항변수화 '변환 이후' 모습을 보면서 아래의 Attributes 결과를 비교해보면 이해하기가 수월할 거예요.

 


# Attributes : active_features_
#               - Indices for active features, actually occur in the training set

In [7]: enc.active_features_

Out[7]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int64)

# 부연설명:  [남, 여, 20대, 30대, 40대, S, A, B, C, D]

 


# Attributes : n_values_
#                - Number of values per feature

In [8]: enc.n_values_

Out[8]: array([2, 3, 5])

# 부연설명: [성별 2개 범주, 연령대 3개 범주, 등급 5개 범주] 


# Attributes : feature_indices_
#                - Indices to feature ranges

In [9]: enc.feature_indices_

Out[9]: array([ 0, 2, 5, 10], dtype=int32)

# 부연설명: [성별 0이상~2미만, 연령대 2이상~5미만, 등급 5이상~10미만]

 

 

 

 

  (3) 적합된 OneHotEncoder()로 새로운 범주형 데이터셋을 이항변수화 변환하기

 

성별 '여성(1)', 연령대 '40대(2)', 등급 'D(4)' 의 범주형 속성을 가진 새로운 고객에 대해서 위의 (1)번에서 적합시킨 OneHotEncoder()의 enc.transform(new data).toarray()를 사용해서 이항변수화 시켜보겠습니다.

 

 

# new data : femail, age_group 40s, D grade

In [10]: data_new = np.array([[1, 2, 4]])

 

# applying OneHotEncoder to new data, returning array

In [11]: enc.transform(data_new).toarray()

Out[11]: array([[ 0., 1., 0., 0., 1., 0., 0., 0., 0., 1.]])

 

 

 

다음번 포스팅에서는 Python으로 연속형 변수를 다수개의 범주로 구분하는 이산형화(discretization) 방법에 대해서 알아보겠습니다.

 

많은 도움 되었기를 바랍니다.

 

 

728x90
반응형
Posted by Rfriend
,