python pandas.crosstab <별별정보>
앞에서 다룬 pandas.pivot_table에 이어 데이터프레임을 재구조화 시킬 수 있는 또 다른 함수에 대해 알아보려한다.
만약 pivot_table에 대해 알아볼 생각이 있다면 필자의 글을 아래 첨부해놓겠다.
python pandas.pivot_table <별별정보>
이번에도 정의한 부분을 링크 걸겠다.
pandas.pivot_table - pandas 0.23.4 document API Reference
특징
crosstab은 cross(가로지르다)와 tabulation (도표 작성, 표, 목록)이라는 말의 줄임말로 여러 개의 데이터 프레임에서 필요한 열을 가져다가 표를 작성할 수 있다는 의미이다. 1개의 데이터 프레임을 구조변형 시키는 pivot_table과는 상당한 차이가 있다. pivot_table은 변수 부분에 반드시 데이터프레임을 변수에 넣어줘야하는 반면 crosstab은 굳이 넣지 않아도 된다.
ex)
pandas.pivot_table(data) #data는 dataframe
변수
index : np.array, pd.Series, list of arrays/Series 모두 가능하며 인덱스는 변수에 반드시 써 넣어줘야하는 변수이다.
columns : np.array, pd.Series, list of arrays/Series 모두 가능하며 열은 변수에 반드시 써 넣어줘야하는 변수이다.
values : array형태면 가능하고 optional 선택사항이다. 다만 values를 쓰기 위해서는 aggfunc를 반드시 특정해주어야한다.
aggfunc : 함수를 넣는 부분이고 optional 선택 사항이다. 다만 변수 선언에 values가 존재해야만 사용이 가능하다.
rownames : 행 이름 변환 해주는 것 default : None
colnames : 열 이름 변환 해주는 것 default : None
margins : 행과 열의 가장자리에 합을 기입해서 보여줄 수 있는 변수이다. default는 None이기 때문에 설정해주지 않으면 표시되지 않는다.
margins_name : margins의 이름을 설정하는 변수로 default : 'All'
dropna : 열의 값들이 모두 Nan으로 되어있는 해당 열을 제외시키기 위한 변수로
이미 default: True가 설정되었기 때문에 자동으로 실행된다. 열의 모든 값들이 0으로 입력되면 그 열은 삭제
normalize : {'all','index','columns'}의 형태나 {0,1}의 형태로 표기가 가능하며 표기된 기준을 토대로 데이터프레임 안의 값들을 기준의 총 값들로 나눈 값으로 표기하여 정규화할 수 있는 변수이다. (필자가 말을 못하여 이해하기 어렵게 하니 아래 예를 살펴보기 바란다.)
설명 순서
1. index, columns2. index, columns, values, aggfunc
3. rownames, colnames
4. margins, margins_name
5. dropna
6. normalize
설명에 앞서 우리가 사용할 데이터 프레임을 먼저 공개한다.
1. index, columns
1-1) index, values 또는 columns, valuespivot_table은 변수에 index, values 혹은 columns, values를 사용해도 조건을 만족하면 실행이 가능했다. 그러나 crosstab은 index나 column이 하나만 모잘라도 실행이 불가하다.
pd.crosstab(index=df.A,values=df.D)
pd.crosstab(columns=df.A,values=df.D)
1-2) index, columns
모두 다중 인덱스 형태로 불러오는 것이 가능하며 여러 개를 사용할 경우 리스트처럼 []안에 넣어 불러야한다. 또한 pivot_table과 달리 데이터프레임을 처음부터 선언하는 것이 아니기 때문에 열을 불러오기 위해서는 DataFrame.column 형태로 불러와야 한다.
pd.crosstab(index=df.A,columns=df.B)
pd.crosstab(index=[df.A,df2.E],columns=[df.B,df2.G])
2. index, columns, values, aggfunc
2-1) value 혹은 aggfunc 하나만 사용할 경우values, aggfunc 모두 선택사항이지만 어떤 것을 사용하던지 반드시 둘은 같이 써야한다.
pd.crosstab(index=df.A,columns=df.B,aggfunc=np.mean)
pd.crosstab(index=df.A,columns=df.B,values=df.D)
=> 실행 오류나면서 ValueError에 서로의 존재가 필요함을 알려준다.
2-2) value, aggfunc 같이 사용할 경우
다른 데이터 프레임의 열들을 불러올 수도 있으며 그 방법은 1에서 설명한 방법과 같다.
ex) [dataframe.column1, dataframe2.column2 ~ etc]
pd.crosstab(index=df.A,columns=df.B,values=df.D,aggfunc=np.mean)
pd.crosstab(index=[df.A,df2.E],columns=[df.B,df2.G],values=df.D,aggfunc=np.sum)
3. rownames, colnames
rownames나 colnames 모두 행이나 열의 이름을 변경시키는 것이다. 그 형태는 sequence 형태로 넣어야 하는데 array로 집어넣어도 된다.1)
pd.crosstab(index=df.A,columns=df.B, rownames=['a'])
2)
a=np.array(['S1'])
b=np.array(['SS1'])
pd.crosstab(index=df.A,columns=df.B, rownames=a, colnames=b)
3)
a=np.array(['S1','S2'])
b=np.array(['SS1'])
pd.crosstab(index=[df.A,df.C],columns=df.B,rownames=a, colnames=b)
4. margins, margins_name
margins는 행과 열의 가장자리에 합을 기입해서 보여줄 수 있는 변수이고 margins_name은margins(default : 'All')의 이름을 바꿔준다.
pd.crosstab(index=df.A,columns=df.B, margins=True)
pd.crosstab(index=df.A,columns=df.B, margins=True,margins_name='Tot')
5. dropna
열의 값들이 모두 0이면 열을 제외시키는 변수로 default=True이다.
시작하기 전에 np.nan을 일정 포함하는 Nan 열을 dataframe에 추가시켰습니다.
pd.crosstab(index=df.A,columns=[df.B,df.Nan], dropna=False)
pd.crosstab(index=df.A,columns=[df.B,df.Nan])
dropna=False일 때 0이 사라지지 않은 것을 확인할 수 있습니다.
6. normalize
정규화하는 방식으로 전체를 값으로 나누어 0~1의 숫자를 만들고 전체 합은 1을 만든다.
normalize=0 or normalize=1로 표기하나 0 대신 False, 1대신 True를 사용하기도 한다.
pd.crosstab(index=df.A,columns=df.B, margins=True,normalize=True)
margins를 통해 전체 합이 1임을 확인 가능하며 각각의 값들이 0~1사이의 값으로 변한 것 또한 확인 가능함을 볼 수 있다.
마무리
다양한 데이터프레임에서 내가 원하는 데이터프레임을 새로 구성할 수 있는 함수 crosstab을 사용하여 많은 것을 변화시킬 수 있을 것으로 예상한다.나중에 이 코드에 .plot(kind=~) 이런식으로 그래프를 그릴 수 있다는 점을 생각하면 데이터 분석에서는 필수적인 요소일 듯 하다.