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

 

재구조화(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이 분석가가 설정할 수 있는 옵션이 조금 더 다양하므로 입맛에 맞게 교차분석도 하고 카이제곱검정도 하고 싶은 분은 아래 링크되어 있는 포스팅을 참고하세요. 

 

 

 

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

 

 

Posted by R Friend R_Friend

자료의 정리와 요약으로

 

- 일변량 범주형 자료의

   도수분포표 (frequency distribution table)

 

- 이변량 범주형 자료의

   분할표 (contingency table)

   카이제곱 검정 (chisquare test)

 

중에서 이번 포스팅에서는 일변량 범주형 자료에 대패 도수분포표(frequency distribution table), 상대도수분포표(relative frequency distribution table)를 사용하여 원자료(raw data)의 정리와 요약에 대해서 알아보도록 하겠습니다.

 

원자료(raw data)를 수집하고 나면 많은 경우 자료의 양이 너무 방대하기 때문에 모집단의 특성, 형태를 파악하기 위해 자료를 정리, 요약할 필요가 생깁니다.

 

영화 Matrix에서 데이터가 어마무시하게 쏟아지는 가운데서 뭔가 의미있는 정보 (agency 출현?)뽑아내는 Operator 'TANK' 기억나는지요?  눈이 빠져라 데이터 홍수 속에서 신호와 소음을 구분하느라 용쓰는게 안쓰러워보이지요? ^^;

 

* 이미지 출처: http://matrixcommunity.org

 

 

자료의 형태(질적/범주형변수 vs. 양적변수)에 따라서, 또 양적변수는 연속형이냐 이산형이냐에 따라서 자료를 정리하고 요약하는 방법, 확률모형 설정, 추정과 검정, 모형 개발 등이 달라집니다.

 

 

[ 자료의 형태 구분 ]

형태 (Type)

순서 여부 (ordinal yes/no)

연속성 여부 (continuous yes/no)

예시 (example) 

  질적 변수

  (Qualitative variable)

  or 범주형 변수

     (Categorical variable) 

 no : 명목형 (nominal)

 이름, 성별, 주소,

 학력, 전화번호 등

 yes : 순서형 (ordinal)

 학년

  양적 변수

  (Quantitative variable)

 yes : 연속형 변수 

        (continuous variable)  

 키, 몸무게, 온도, 습도 등

 no  : 이산형 변수

        (descrete variable)

 나이

 

 

 

 

 

분석 기법은 변수가 몇개냐, 변수의 형태가 무엇이냐(범주형 변수와 연속형 변수의 2개로 구분)해서 간략하게 표로 제시해보면 아래와 같습니다.

 

 

일변량 (one variable)

 

 자료 형태

분석 기법 

 범주형 변수

(categorical variable)

 

 <표(table)를 이용한 정리와 요약 >

 

 도수분포표 (frequency distribution table)

 

 연속형 변수

(continuous variable)

 

 < 통계량(statistics)을 이용한 요약 >

 

 - 중심 경향 : 평균 (mean), 중앙값 (median), 최빈값 (mode)

 - 퍼짐 정도 : 분산 (variance), 표준편차(standard deviation),

                 범위 (range), 사분위수(IQR: Inter Quantile Rnage)

 - 치우침 정도 : 왜도 (skewness), 첨도 (kurtosis)

 

※ 그래프 분석 병행 매우 중요

 

 

이변량 (two variables)

 

                Y 변수

  X 변수 

범주형 변수

(categorical variable)

연속형 변수

(continuous variable)

 범주형 변수

(categorical variable)

  분할표 (contingency table)

  카이제곱 검정 (chi-square test)

  t-Test

  ANOVA

 연속형 변수

(continuous variable)

  의사결정나무 (decision tree)

  로지스틱회귀분석 (rogistic regression)

 상관분석 (correlation analysis)

 회귀분석 (regression analysis) 

※ 그래프 분석 병행 매우 중요

 

 

 

그럼, R의 table(), xtabs() 함수를 이용하여 도수분포표, 상대도수분포표로 일변량(one variable) 범주형 자료(categorical variable)에 대한 정리와 요약을 해보겠습니다.

 

MASS 패키지에 내장된 Cars93 데이터프레임의 차종형태(Type) 변수를 분석해 보겠습니다.

 

> library(MASS)
> str(Cars93)
'data.frame':	93 obs. of  27 variables:
 $ Manufacturer      : Factor w/ 32 levels "Acura","Audi",..: 1 1 2 2 3 4 4 4 4 5 ...
 $ Model             : Factor w/ 93 levels "100","190E","240",..: 49 56 9 1 6 24 54 74 73 35 ...
 $ Type              : Factor w/ 6 levels "Compact","Large",..: 4 3 1 3 3 3 2 2 3 2 ...
 $ Min.Price         : num  12.9 29.2 25.9 30.8 23.7 14.2 19.9 22.6 26.3 33 ...
 $ Price             : num  15.9 33.9 29.1 37.7 30 15.7 20.8 23.7 26.3 34.7 ...
 $ Max.Price         : num  18.8 38.7 32.3 44.6 36.2 17.3 21.7 24.9 26.3 36.3 ...
 $ MPG.city          : int  25 18 20 19 22 22 19 16 19 16 ...
 $ MPG.highway       : int  31 25 26 26 30 31 28 25 27 25 ...
 $ AirBags           : Factor w/ 3 levels "Driver & Passenger",..: 3 1 2 1 2 2 2 2 2 2 ...
 $ DriveTrain        : Factor w/ 3 levels "4WD","Front",..: 2 2 2 2 3 2 2 3 2 2 ...
 $ Cylinders         : Factor w/ 6 levels "3","4","5","6",..: 2 4 4 4 2 2 4 4 4 5 ...
 $ EngineSize        : num  1.8 3.2 2.8 2.8 3.5 2.2 3.8 5.7 3.8 4.9 ...
 $ Horsepower        : int  140 200 172 172 208 110 170 180 170 200 ...
 $ RPM               : int  6300 5500 5500 5500 5700 5200 4800 4000 4800 4100 ...
 $ Rev.per.mile      : int  2890 2335 2280 2535 2545 2565 1570 1320 1690 1510 ...
 $ Man.trans.avail   : Factor w/ 2 levels "No","Yes": 2 2 2 2 2 1 1 1 1 1 ...
 $ Fuel.tank.capacity: num  13.2 18 16.9 21.1 21.1 16.4 18 23 18.8 18 ...
 $ Passengers        : int  5 5 5 6 4 6 6 6 5 6 ...
 $ Length            : int  177 195 180 193 186 189 200 216 198 206 ...
 $ Wheelbase         : int  102 115 102 106 109 105 111 116 108 114 ...
 $ Width             : int  68 71 67 70 69 69 74 78 73 73 ...
 $ Turn.circle       : int  37 38 37 37 39 41 42 45 41 43 ...
 $ Rear.seat.room    : num  26.5 30 28 31 27 28 30.5 30.5 26.5 35 ...
 $ Luggage.room      : int  11 15 14 17 13 16 17 21 14 18 ...
 $ Weight            : int  2705 3560 3375 3405 3640 2880 3470 4105 3495 3620 ...
 $ Origin            : Factor w/ 2 levels "USA","non-USA": 2 2 2 2 2 1 1 1 1 1 ...
 $ Make              : Factor w/ 93 levels "Acura Integra",..: 1 2 4 3 5 6 7 9 8 10 ...

 

 

 

(1) 도수분포표(frequency distribution table) : table(), xtabs()

 

> ##----------------------------------------------------------
> ## 일변량 도수분포표(frequency distribution table) : table(), xtabs()
> ##----------------------------------------------------------
>
> # frequency distribution table : table()
> Car_table_1 <- with(Cars93, table(Type))
> Car_table_1
Type
Compact   Large Midsize   Small  Sporty     Van 
     16      11      22      21      14       9 
> 
> # frequency distribution table : xtabs()
> Car_table_2 <- xtabs(~Type, data=Cars93)
> Car_table_2
Type
Compact   Large Midsize   Small  Sporty     Van 
     16      11      22      21      14       9

 

 

table()은 데이터 프레임을 할당할 수 있는 없어서 with() 함수를 사용했습니다. (attach() 함수를 사용해도 됨).

반면에 xtabs()는 xtabs(formula, data) 형식으로서 뒤에 데이터 프레임을 명시적으로 할당하는 문법입니다.

 

 

 

(2) 상대도수분포표(relative frequency distribution table) : prop.table()

 

 
> options("digits" = 2) # 소수점 자리수 설정 (decimal point setting)
> prop.table(Car_table_1)
Type
Compact   Large Midsize   Small  Sporty     Van 
  0.172   0.118   0.237   0.226   0.151   0.097 

 

 

 

(3) Bar plot : barplot()

 

> # bar plot
> barplot(Car_table_1, 
+         main = "Bar Plot of Car Type", 
+         xlab = "Car Type", ylab = "conuts", 
+         col = c("yellow"))

 

 

 

 

아무래도 그래프로 보는 것이 표로 보는 것보다는 직관적인 이해, 가독성이 우수합니다.

 

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

 

이번 포스팅이 도움이 되었다면 아래의 '공감 ~♡'를 꾸욱 눌러주세요. ^^

 

Posted by R Friend R_Friend