본문 바로가기
AI/데이터 사이언스

[AI 부트캠프] DAY 25 - 파이썬 EDA 5

by HOHHOH 2023. 8. 22.

[오늘의 일지]

파이썬 EDA 실시간 강의 - Pandas, Seaborn

[상세 내용]

파이썬 EDA

Pandas 추가 내용

- pandas를 이용하면 mysql이나 oracle 같은 sql 언어를 사용하는 프로그램처럼 데이터를 합치는 기능인 join을 사용할 수 있습니다. 그 기능을 정리해 보겠습니다. 정리할 함수는 concat()과 merge()입니다. 일단 데이터를 만들어 보겠습니다.

# 넘파이 판다스 기능 사용
import numpy as np
import pandas as pd

# 데이터 만들어 놓기(실제데이터가 있다며 더 좋다)
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'], 
                    'B': ['B0', 'B1', 'B2', 'B3'],
                    'C': ['C0', 'C1', 'C2', 'C3'],
                    'D': ['D0', 'D1', 'D2', 'D3']},
                   index=[0, 1, 2, 3])

df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
                    'B': ['B4', 'B5', 'B6', 'B7'],
                    'C': ['C4', 'C5', 'C6', 'C7'],
                    'D': ['D4', 'D5', 'D6', 'D7']},
                   index=[4, 5, 6, 7])

df3 = pd.DataFrame({'A': ['A8', 'A9', 'A10', 'A11'],
                    'B': ['B8', 'B9', 'B10', 'B11'],
                    'C': ['C8', 'C9', 'C10', 'C11'],
                    'D': ['D8', 'D9', 'D10', 'D11']},
                   index=[8, 9, 10, 11])

df4 = pd.DataFrame({'A': ['A1', 'A2', 'A4', 'A5'], 
                    'E': ['E0', 'E1', 'E2', 'E3'],
                    'F': ['F0', 'F1', 'F2', 'F3']})

 

- concat() 사용하기 : 일단 칼럼이 같은 데이터끼리 아무 조건도 넣지 않고 사용해 보겠습니다. concat()의 디폴트 값은 칼럼을 기준으로 합쳐주는 것입니다.  위에 데이터를 보시면 df4는 인덱스를 지정해주지 않았지만 디폴트값으로 0부터 시작합니다. 그리고 데이터를 칼럼을 기준으로 합쳤을 때 겹치는 칼럼이 없다면 Null으로 대체됩니다. 마지막으로 칼럼을 기준으로 하지 않고 로우(행)를 기준으로 합칠 수도 있는데 조건에 axis=1을 붙여주면 됩니다. 이 말은 디폴트 값이 axis=0이었다는 말이 됩니다.

# 그냥 합치기 (concatenation)
pd.concat([df1,df2,df3])
>>>
	A	B	C	D
4	A4	B4	C4	D4
5	A5	B5	C5	D5
6	A6	B6	C6	D6
7	A7	B7	C7	D7
0	A0	B0	C0	D0
1	A1	B1	C1	D1
2	A2	B2	C2	D2
3	A3	B3	C3	D3
8	A8	B8	C8	D8
9	A9	B9	C9	D9
10	A10	B10	C10	D10
11	A11	B11	C11	D11

# 겹치는 것이 없다면 Null로 대체
pd.concat([df1, df4])
>>>
	A	B	C	D	E	F
0	A0	B0	C0	D0	NaN	NaN
1	A1	B1	C1	D1	NaN	NaN
2	A2	B2	C2	D2	NaN	NaN
3	A3	B3	C3	D3	NaN	NaN
0	A1	NaN	NaN	NaN	E0	F0
1	A2	NaN	NaN	NaN	E1	F1
2	A4	NaN	NaN	NaN	E2	F2
3	A5	NaN	NaN	NaN	E3	F3

# 칼럼이 아닌 로우를 기준으로 합칠 수도 있다
pd.concat([df1, df4], axis=1)
>>>
	A	B	C	D	A	E	F
0	A0	B0	C0	D0	A1	E0	F0
1	A1	B1	C1	D1	A2	E1	F1
2	A2	B2	C2	D2	A4	E2	F2
3	A3	B3	C3	D3	A5	E3	F3

pd.concat([df1, df2, df3], axis=1)
>>>

	A	B	C	D	A	B	C	D	A	B	C	D
0	A0	B0	C0	D0	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN
1	A1	B1	C1	D1	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN
2	A2	B2	C2	D2	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN
3	A3	B3	C3	D3	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN
4	NaN	NaN	NaN	NaN	A4	B4	C4	D4	NaN	NaN	NaN	NaN
5	NaN	NaN	NaN	NaN	A5	B5	C5	D5	NaN	NaN	NaN	NaN
6	NaN	NaN	NaN	NaN	A6	B6	C6	D6	NaN	NaN	NaN	NaN
7	NaN	NaN	NaN	NaN	A7	B7	C7	D7	NaN	NaN	NaN	NaN
8	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	A8	B8	C8	D8
9	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	A9	B9	C9	D9
10	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	A10	B10	C10	D10
11	NaN	NaN	NaN	NaN	NaN	NaN	NaN	NaN	A11	B11	C11	D11

 

- merge() 사용하기 : sql에서 교집합을 만드는 inner join이나  교집합을 제외한 자기 데이터를 나타내는 left(right) join을 나타내기 위해 merge()를 사용할 수 있다. 조건에서 먼저 입력하는 데이터프레임 기준으로 left가 되며 사용방법은 how를 이용합니다. 여기서 inner join을 사용했을 때 값은 겹치는 값을 포함한 양쪽 데이터의 칼럼의 값들을 가져오는 것을 실행 결과로 확인할 수 있습니다.

df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'], 
                    'B': ['B0', 'B1', 'B2', 'B3'],
                    'C': ['C0', 'C1', 'C2', 'C3'],
                    'D': ['D0', 'D1', 'D2', 'D3']},
                   index=[0, 1, 2, 3])

df4 = pd.DataFrame({'A': ['A1', 'A2', 'A4', 'A5'], 
                    'B': ['B2', 'B3', 'B4', 'B5'],
                    'C': ['C3', 'C4', 'C5', 'C6'],})
                    
# 위와 같은 데이터프레임이 있다고 할 때 inner join 사용하기 조건에 on은 겹치는 기준이 됩니다. 
# 겹치지 않는 것은 x와 y를 이용해서 표현해주는데 겹치는 값이 있는 칼러만 가져오는 겁니다.
pd.merge(df1, df4, on="A")
>>>
	A	B_x	C_x	D	B_y	C_y
0	A1	B1	C1	D1	B2	C3
1	A2	B2	C2	D2	B3	C4

pd.merge(df1, df4, on='B')
>>>
	A_x	B	C_x	D	A_y	C_y
0	A2	B2	C2	D2	A1	C3
1	A3	B3	C3	D3	A2	C4

pd.merge(df1, df4, on='C')
>>>
	A_x	B_x	C	D	A_y	B_y
0	A3	B3	C3	D3	A1	B2

# left join
pd.merge(df1,df4, on="A", how='left')
>>>
	A	B_x	C_x	D	B_y	C_y
0	A0	B0	C0	D0	NaN	NaN
1	A1	B1	C1	D1	B2	C3
2	A2	B2	C2	D2	B3	C4
3	A3	B3	C3	D3	NaN	NaN

 

- pivot Table을 이용하기 : pivot table이란 기존 테이블 구조를 특정 column을 기준으로 재구조화한 테이블을 말합니다. 특정 column을 기준으로 pivot 하기 때문에 어떤 column에 어떤 연산을 하느냐에 따라서 만들어지는 결과가 바뀝니다.

# 성별을 기준으로 생존률 파악 --> Mean vs Sum
pd.pivot_table(data=titanic,index='Sex',values=['Survived'],aggfunc=['count','sum','mean'])
>>>
        count		sum		mean
        Survived	Survived	Survived
Sex			
female	314		233		0.742038
male	577		109		0.188908

# 사회 계급을 기준으로 생존률 파악
pd.pivot_table(data=titanic,index='Pclass',values=['Survived'],aggfunc=['count','sum','mean'])
>>>
		count		sum		mean
		Survived	Survived	Survived
Pclass			
1		216		136		0.629630
2		184		87		0.472826
3		491		119		0.242363

# 사회 계급을 기준으로 성별을 나눠서 생존률 파악
pd.pivot_table(data=titanic,index=['Pclass','Sex'],values=['Survived'],aggfunc=['count','sum','mean'])
>>>
			count		sum		mean
			Survived	Survived	Survived
Pclass	Sex			
1	female		94		91		0.968085
	male		122		45		0.368852
2	female		76		70		0.921053
	male		108		17		0.157407
3	female		144		72		0.500000
	male		347		47		0.135447

 

- 그룹별 pivot table 확인

titanic.pivot_table
>>>
<bound method DataFrame.pivot_table of      PassengerId  Survived  Pclass  \
0              1         0       3   
1              2         1       1   
2              3         1       3   
3              4         1       1   
4              5         0       3   
..           ...       ...     ...   
886          887         0       2   
887          888         1       1   
888          889         0       3   
889          890         1       1   
890          891         0       3   

                                                  Name     Sex   Age  SibSp  \
0                              Braund, Mr. Owen Harris    male  22.0      1   
1    Cumings, Mrs. John Bradley (Florence Briggs Th...  female  38.0      1   
2                               Heikkinen, Miss. Laina  female  26.0      0   
3         Futrelle, Mrs. Jacques Heath (Lily May Peel)  female  35.0      1   
4                             Allen, Mr. William Henry    male  35.0      0   
..                                                 ...     ...   ...    ...   
886                              Montvila, Rev. Juozas    male  27.0      0   
887                       Graham, Miss. Margaret Edith  female  19.0      0   
888           Johnston, Miss. Catherine Helen "Carrie"  female   NaN      1   
889                              Behr, Mr. Karl Howell    male  26.0      0   
890                                Dooley, Mr. Patrick    male  32.0      0   

     Parch            Ticket     Fare Cabin Embarked  
0        0         A/5 21171   7.2500   NaN        S  
1        0          PC 17599  71.2833   C85        C  
2        0  STON/O2. 3101282   7.9250   NaN        S  
3        0            113803  53.1000  C123        S  
4        0            373450   8.0500   NaN        S  
..     ...               ...      ...   ...      ...  
886      0            211536  13.0000   NaN        S  
887      0            112053  30.0000   B42        S  
888      2        W./C. 6607  23.4500   NaN        S  
889      0            111369  30.0000  C148        C  
890      0            370376   7.7500   NaN        Q  

[891 rows x 12 columns]>

 

- 번외 데이터프레임에서 null을 제외하는 함수

# 결측치를 하나라도 포함하고 있는 데이터가 몇개나 있는지 확인.
titanic.loc[titanic.isnull().any(axis=1)]

# 원한는 칼럼을 제거하는 방법
titanic.drop(columns=['Cabin']).dropna()

# 결측치가 있는 모든 행을 제거하는 방법(실제 데이터에서는 조심해야 한다)
titanic.dropna()

 

Seaborn 세부적인 부분

- Seaborn이라는 라이브러리 자체가 matplotlib을 배경으로 하기 때문에 matplotlib에서 한글 폰트를 이용하는 방법을 알려드리겠습니다. 윈도우랑 맥os의 방법이 조금 차이가 있는데 그건 폰트의 위치가 다르기 때문입니다.

# 폰트 설정 방법 2
import matplotlib
import matplotlib.font_manager as fm

#plt.rc('font',family='AppleGothic')
# font_location = '/System/Library/Fonts/AppleSDGothicNeo.ttc' # For mac
# font_location = 'C:/Windows/Fonts/Malgun.ttf' # For Windows
font_name = fm.FontProperties(fname=font_location).get_name()
print(font_name)
matplotlib.rc('font', family=font_name)

 

- Seaborndml -plot에서 막대의 위치는 x, y의 설정에 의해서 간편하게 변경할 수 있다.

# penguin 데이터에 histplot을 출력합니다.
sns.histplot(data=data ,y='bill_length_mm', bins=20, hue= 'species', multiple='stack')

y에 컬럼을 설정했을 때

 

# penguin 데이터에 histplot을 출력합니다.
sns.histplot(data=data ,x='bill_length_mm', bins=20, hue= 'species', multiple='stack')

x엘 컬럼을 설정했을 때

 

- displot을 사용할 때 칼럼 안에 종류에 따라 여러 개의 그래프가 나올 수 있는데 col과 row를 이용하면 기준을 바꾸면서 사용할 수 있습니다. 물론 원하는 칼럼을 추가한다면 col과 row를 동시에 사용하는 것도 가능합니다.

# penguin 데이터에 displot을 출력합니다.
sns.displot(data=data, x= 'bill_length_mm', col='species', kind='hist', hue='species', palette='viridis')

col 기준일 때

 

# penguin 데이터에 displot을 출력합니다.
sns.displot(data=data, x= 'bill_length_mm', row='species', kind='hist', hue='species', palette='viridis')

row 기준일 때

# penguin 데이터에 displot을 출력합니다.
sns.displot(data=data, x='bill_length_mm', row='species', col="sex", kind='hist', hue='species', palette='viridis'

칼럼 2개를 이용해서 col과 row를 둘다 사용

 

- 그 밖에 세부적인 설정하기

# 그래프의 크기 설정
plt.figure(figsize=(12, 6)) 

# 제목을 설정할 때도 fontsize를 이용해서 크기 설정
plt.title("title", fontsize=16)

# 그래프의 세부적인 색 설정 palette 이용하기 색은 홈페이지에 들어가면 엄첨 많이 존재한다.
palette='viridis' 이런 식으로 -plot 안에서 설정한다

# 그래프 저장 하기(경로는 원하는 경로를 입력하면 되고 디폴트값은 현재 ipynb파일이 있는 위치입니다)
plt.savefig('sample_barplot.png')

 

[마무리]

 오늘은 복습 위주로 지난주에 배운 내용을 학습했습니다. 이번주는 오전에 실시간 강의를 진행하고 오후에는 온라인 녹화 강의를 복습하는 방식으로 이루어져 있는데요. 반복 학습을 한다는 점에서 아주 좋은 학습인 거 같습니다.

반응형

댓글