Professional Documents
Culture Documents
데이터 확인
[1]
import pandas as pd
출력 Mounted at /gdrive
[3]
drive_path = '/gdrive/My Drive/Colab/'
출력
- 1 -
DataFrame 확인
계산 가능한 데이터에 대해 Column 별로 데이터의 갯수, 평균, 표준편차, 최소/최대값
등의 정보를 보여줌
[5]
df.describe()
출력
[6]
df.info()
<class 'pandas.core.frame.DataFrame'>
Index: 8 entries, 1번 to 8번
Data columns (total 9 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 이름 8 non-null object
1 학교 8 non-null object
2 키 8 non-null int64
출력
3 국어 8 non-null int64
4 영어 8 non-null int64
5 수학 8 non-null int64
6 과학 8 non-null int64
7 사회 8 non-null int64
8 sw특기 6 non-null object
dtypes: int64(6), object(3)
memory usage: 640.0+ bytes
- 2 -
[7]
df.head()
출력
[8]
df.head(7) #처음 7개의 row를 가져옴
출력
[9]
df.tail() #마지막 5개 row를 가져옴
출력
- 3 -
[10]
df.tail(3) #마지막 3개 row를 가져옴
출력
[11]
df.values
[12]
df.index
출력 Index(['1번', '2번', '3번', '4번', '5번', '6번', '7번', '8번'], dtype='object', name='지원번호')
[13]
df.columns
출력 Index(['이름', '학교', '키', '국어', '영어', '수학', '과학', '사회', 'sw특기'], dtype='object')
[14]
df.shape
출력 (8, 9)
- 4 -
[15]
df
출력
Series 확인
[16]
df['키'].describe()
count 8.000000
mean 188.000000
std 9.985704
min 168.000000
출력 25% 186.250000
50% 188.000000
75% 191.750000
max 202.000000
Name: 키, dtype: float64
[17]
df['키'].min()
출력 168
[18]
df['키'].max()
출력 202
- 5 -
[19]
df['키'].nlargest(3) #키 큰 사람 순서대로 3명 데이터
지원번호
6번 202
출력 1번 197
8번 190
Name: 키, dtype: int64
[20]
df['키'].mean()
출력 188.0
[21]
df['키'].sum()
출력 1504
[22]
df['sw특기'].count()
출력 6
[23]
df['학교'].unique()
[24]
df['학교'].nunique()
출력 2
- 6 -
11. 데이터 선택(기본)
[1]
import pandas as pd
출력 Mounted at /gdrive
[3]
drive_path = '/gdrive/My Drive/Colab/'
출력
- 1 -
Column 선택 (label)
[5]
df['이름']
지원번호
1번 채치수
2번 정대만
3번 송태섭
4번 서태웅
출력
5번 강백호
6번 변덕규
7번 황태산
8번 윤대협
Name: 이름, dtype: object
[6]
df['키']
지원번호
1번 197
2번 184
3번 168
4번 187
출력
5번 188
6번 202
7번 188
8번 190
Name: 키, dtype: int64
- 2 -
[7]
df[['이름','키']]
출력
출력 Index(['이름', '학교', '키', '국어', '영어', '수학', '과학', '사회', 'sw특기'], dtype='object')
[9]
df.columns[0]
출력 '이름'
[10]
df.columns[2]
출력 '키'
- 3 -
[11]
df[df.columns[0]] #df['이름'] 과 동일한 동작
지원번호
1번 채치수
2번 정대만
3번 송태섭
4번 서태웅
출력
5번 강백호
6번 변덕규
7번 황태산
8번 윤대협
Name: 이름, dtype: object
[12]
df[df.columns[-1]] #맨 끝에 있는 값을 가져옴
지원번호
1번 Python
2번 Java
3번 Javascript
4번 NaN
출력
5번 NaN
6번 C
7번 PYTHON
8번 C#
Name: sw특기, dtype: object
- 4 -
슬라이싱
[13]
df
출력
[14]
df['영어'][0:5]
지원번호
1번 85
2번 35
출력 3번 75
4번 60
5번 20
Name: 영어, dtype: int64
[15]
df[['이름','키']][:3]
출력
- 5 -
[16]
df[3:]
출력
- 6 -
12. 데이터 선택(loc)
이름을 이용하여 원하는 row에서 원하는 col 선택
[1]
import pandas as pd
출력 Mounted at /gdrive
[3]
drive_path = '/gdrive/My Drive/Colab/'
출력
- 1 -
[5]
df.loc['1번'] # index 1번에 해당하는 전체 데이터
이름 채치수
학교 북산고
키 197
국어 90
영어 85
출력
수학 100
과학 95
사회 85
sw특기 Python
Name: 1번, dtype: object
[6]
df.loc['5번'] # index 5번에 해당하는 전체 데이터
이름 강백호
학교 북산고
키 188
국어 15
영어 20
출력
수학 10
과학 35
사회 10
sw특기 NaN
Name: 5번, dtype: object
[7]
df.loc['1번','국어'] # index 1번에 해당하는 국어 데이터
출력 90
- 2 -
[8]
df.loc[['1번','2번'],'영어'] # index 1번, 2번에 헤당하는 영어 데이터
지원번호
1번 85
출력
2번 35
Name: 영어, dtype: int64
[9]
df.loc[['1번','2번'],['영어','수학']] # index 1번, 2번에 해당하는 영어, 수학 데이터
출력
[10]
df.loc['1번':'5번','국어':'사회'] # index 1번부터 5번까지, 국어부터 사회까지 데이터
출력
- 3 -
14. 데이터 선택(조건)
조건에 해당하는 데이터 선택
[1]
import pandas as pd
출력 Mounted at /gdrive
[3]
drive_path = '/gdrive/My Drive/Colab/'
출력
- 1 -
[5]
df['키'] >= 185 # 학생들의 키가 185 이상인지 여부를 True / False
지원번호
1번 True
2번 False
3번 False
4번 True
출력
5번 True
6번 True
7번 True
8번 True
Name: 키, dtype: bool
출력
[7]
df[~filt] # filter 를 역으로 적용
출력
- 2 -
[8]
df[df['키'] >= 185]
출력
[9]
df.loc[df['키'] >= 185, '수학'] # 키가 185 이상인 학생들의 수학 데이터
지원번호
1번 100
4번 70
5번 10
출력
6번 95
7번 45
8번 90
Name: 수학, dtype: int64
출력
- 3 -
다양한 조건
& 그리고
[11] # 키가 185 이상인 북산고 학생 데이터
df.loc[(df['키'] >= 185) & (df['학교'] == '북산고')]
출력
| 또는
[12] # 키가 170 보다 작거나, 200 보다 큰 학생 데이터
df.loc[(df['키'] < 170) | (df['키'] > 200)]
출력
str 함수
[13]
df['이름'].str.startswith('송') # '송'씨 성을 가진 사람
지원번호
1번 False
2번 False
3번 True
4번 False
출력
5번 False
6번 False
7번 False
8번 False
Name: 이름, dtype: bool
- 4 -
[14] filt = df['이름'].str.contains('태') #이름에 '태'가 들어가는 사람
df[filt]
출력
[15]
df[~filt] # 이름에 '태'가 들어가는 사람을 제외
출력
출력
- 5 -
[17]
df
출력
출력
# 에러 일부 생략
출력
ValueError: Cannot mask with non-boolean array containing NA / NaN values
- 6 -
[20]
df['sw특기'].str.lower().isin(langs)
지원번호
1번 True
2번 True
3번 False
4번 False
출력
5번 False
6번 False
7번 True
8번 False
Name: sw특기, dtype: bool
[21]
df['sw특기'].str.contains('Java', na=True) # NaN 데이터에 대해서 True로 설정
지원번호
1번 False
2번 True
3번 True
4번 True
출력
5번 True
6번 False
7번 False
8번 False
Name: sw특기, dtype: bool
[22]
df['sw특기'].str.contains('Java', na=False) # NaN 데이터에 대해서 False로 설정
지원번호
1번 False
2번 True
3번 True
4번 False
출력
5번 False
6번 False
7번 False
8번 False
Name: sw특기, dtype: bool
- 7 -
[23] filt = df['sw특기'].str.contains('Java', na=False)
df[filt]
출력
- 8 -
15. 결측치
비어 있는 데이터
[1]
import pandas as pd
출력 Mounted at /gdrive
[3]
drive_path = '/gdrive/My Drive/Colab/'
출력
- 1 -
NaN 확인하기 isnull
[5]
df.isnull()
출력
[6]
df.isnull().sum() # 각 열의 NaN 데이터 개수 계산하기
이름 0
학교 0
키 0
국어 0
영어 0
출력
수학 0
과학 0
사회 0
sw특기 2
dtype: int64
- 2 -
데이터 채우기 fillna
[7]
df.fillna('') # NaN 데이터를 빈 칸으로 채움
출력
[8]
df.fillna('없음')
출력
- 3 -
[9] import numpy as np
df['학교'] = np.nan
df
출력
[10]
df.fillna('모름')
출력
[11]
df.fillna('모름', inplace=True)
- 4 -
[12]
df
출력
출력
- 5 -
[15]
df
출력
- 6 -
데이터 제외하기 dropna
[16] df = pd.read_excel(drive_path + 'score.xlsx', index_col='지원번호')
df
출력
[18]
df
출력
- 7 -
[19] df = pd.read_excel(drive_path + 'score.xlsx', index_col='지원번호')
df
출력
- 8 -
• axis : index or columns
• how : any or all
[20]
df.dropna(axis='index',how='any') # NaN이 하나라도 있는 row 삭제
출력
[21]
df.dropna(axis='columns') # NaN이 하나라도 있는 column 삭제
출력
- 9 -
[22] df['학교'] = np.nan
df
출력
출력
- 10 -
16. 데이터 정렬
[1]
import pandas as pd
출력 Mounted at /gdrive
[3]
drive_path = '/gdrive/My Drive/Colab/'
출력
- 1 -
[5]
df.sort_values('키') # 키 기준으로 오름차순 정렬
출력
[6]
df.sort_values('키', ascending=False) # 키 기준으로 내림차순 정렬
출력
[7]
df.sort_values(['수학','영어']) # 수학, 영어 점수 기준으로 오름차순
출력
- 2 -
[8]
df.sort_values(['수학','영어'], ascending=False) # 수학, 영어 점수 기준으로 내림차순
출력
출력
[10]
df['키'].sort_values()
지원번호
3번 168
2번 184
4번 187
5번 188
출력
7번 188
8번 190
1번 197
6번 202
Name: 키, dtype: int64
- 3 -
[11]
df['키'].sort_values(ascending=False)
지원번호
6번 202
1번 197
8번 190
5번 188
출력
7번 188
4번 187
2번 184
3번 168
Name: 키, dtype: int64
[12]
df.sort_index()
출력
[13]
df.sort_index(ascending=False)
출력
- 4 -
17. 데이터 수정
[1]
import pandas as pd
출력 Mounted at /gdrive
[3]
drive_path = '/gdrive/My Drive/Colab/'
출력
- 1 -
Column 수정
[5]
df['학교'].replace({'북산고':'상북고', '능남고':'무슨고'})
지원번호
1번 상북고
2번 상북고
3번 상북고
4번 상북고
출력
5번 상북고
6번 무슨고
7번 무슨고
8번 무슨고
Name: 학교, dtype: object
[6]
df
출력
[7]
df['학교'].replace({'북산고':'상북고'}, inplace=True)
- 2 -
[8]
df
출력
[9]
df['sw특기'].str.lower()
지원번호
1번 python
2번 java
3번 javascript
4번 NaN
출력
5번 NaN
6번 c
7번 python
8번 c#
Name: sw특기, dtype: object
[10]
df['sw특기'] = df['sw특기'].str.lower()
- 3 -
[11]
df
출력
[12]
df['sw특기'] = df['sw특기'].str.upper()
[13]
df
출력
- 4 -
[14] df['학교'] = df['학교'] + '등학교' # 학교 데이터 + 등학교
df
출력
Column 추가
[15] df['총합'] = df['국어'] + df['영어'] + df['수학'] + df['과학'] + df['사회']
df
출력
[16]
90 + 85 + 100 + 95 +85
출력 455
- 5 -
[17] df['결과'] = 'Fail'
df
출력
출력
- 6 -
Column 삭제
[19]
df.drop(columns=['총합']) # 총합 Column을 삭제
출력
[20]
df
출력
- 7 -
[21]
df.drop(columns=['국어','영어','수학']) #국어, 영어, 수학 Column을 삭제
출력
[22]
df
출력
- 8 -
Row 삭제
[23]
df.drop(index='4번') # 4번 학생 데이터 row 삭제
출력
출력
[25]
df[filt].index
[26]
df.drop(index=df[filt].index)
출력
- 9 -
[27]
df
출력
Row 추가
[28] df.loc['9번'] = ['이정환', '해남고등학교', 184, 90, 90, 90, 90, 90, 'Kotlin', 450, 'Pass']
df
출력
- 10 -
Cell 수정
[29] # 4번 학생의 sw특기 데이터를 Python으로 변경
df.loc['4번','sw특기'] = 'Python'
df
출력
출력
- 11 -
Column 순서 변경
[31] cols = list(df.columns)
cols
출력 ['이름', '학교', '키', '국어', '영어', '수학', '과학', '사회', 'sw특기', '총합', '결과']
출력
[33] df = df[['결과','이름','학교']]
df
출력
- 12 -
Column 이름 변경
[34]
df.columns
출력
출력
- 13 -
[37]
df.rename(columns={'이름':'성명', '학교':'고등학교'})
출력
출력
- 14 -
18. 그룹화
동일한 값을 가진 것들끼리 합쳐서 통계 또는 평균 등의 값을 계산하기 위해 사용
[1]
import pandas as pd
출력 Mounted at /gdrive
[3]
drive_path = '/gdrive/My Drive/Colab/'
출력
- 1 -
[5]
df.groupby('학교')
[6]
df.groupby('학교').get_group('북산고')
출력
[7]
df.groupby('학교').get_group('능남고')
출력
[8]
df.groupby('학교').mean() #계산 가능한 데이터들의 평균값
출력
- 2 -
[9]
df.groupby('학교').size() #각 그룹의 크기
학교
능남고 3
출력
북산고 5
dtype: int64
출력 3
출력
- 3 -
[13] df['학년'] = [3, 3, 2, 1, 1, 3, 2, 2] # 학년 Column 추가
df
출력
[14]
df.groupby(['학교','학년']).mean() # 학교별, 학년별 평균 데이터
출력
[15]
df.groupby('학년').mean() # 학년별 평균 데이터
출력
- 4 -
[16]
df.groupby('학년').mean().sort_values('키')
출력
[17]
df.groupby('학년').mean().sort_values('키', ascending=False)
출력
[18]
df.groupby(['학교','학년']).sum()
출력
- 5 -
[19] # 학교로 그룹화를 한 뒤에 각 학교별 이름과 sw특기 데이터의 수를 가져옴
df.groupby('학교')[['이름','sw특기']].count()
출력
- 6 -
[23] # 학생들의 수 데이터를 퍼센트로 비교하여 가져옴
school['학년'].value_counts(normalize=True).loc['북산고']
학년
1 0.4
출력 3 0.4
2 0.2
Name: 학년, dtype: float64
- 7 -
19. seaborn으로 데이터 시각화하기
[1]
import seaborn as sns
[3]
sns.get_dataset_names()
['anagrams',
'anscombe',
'attention',
'brain_networks',
'car_crashes',
'diamonds',
'dots',
'exercise',
'flights',
출력 'fmri',
'gammas',
'geyser',
'iris',
'mpg',
'penguins',
'planets',
'taxis',
'tips',
'titanic']
- 1 -
음식점에서 지불한 팁 금액, 손님 정보 등을 확인할 수 있는 'tips' 데이터셋을 사용
• total_bill: 음식가격
• tip: 팁 금액
• sex: 성별
• smoker: 흡연여부
• day: 방문요일
• time: 방문시간
• size: 인원수
[4] df = sns.load_dataset('tips')
df.head()
출력
[5]
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 244 entries, 0 to 243
Data columns (total 7 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 total_bill 244 non-null float64
1 tip 244 non-null float64
출력
2 sex 244 non-null category
3 smoker 244 non-null category
4 day 244 non-null category
5 time 244 non-null category
6 size 244 non-null int64
dtypes: category(4), float64(2), int64(1)
memory usage: 7.4 KB
- 2 -
[6]
df.describe()
출력
[7]
df['sex'].unique()
['Female', 'Male']
출력
Categories (2, object): ['Male', 'Female']
[8]
df['sex'].value_counts()
Male 157
출력 Female 87
Name: sex, dtype: int64
- 3 -
산점도 (scatterplot)
산점도는 x축 변수와 y축 변수의 상관관계를 확인할 때 사용하는 그래프
비싼 음식을 먹은 사람들이 팁을 많이 지불했을까요? 음식가격과 팁의 상관관계 확인
[9]
sns.scatterplot(x=df['total_bill'], y=df['tip'])
<matplotlib.axes._subplots.AxesSubplot at 0x7f876ac25090>
출력
<matplotlib.axes._subplots.AxesSubplot at 0x7f876ac0cb90>
출력
- 4 -
인원수에 따른 값의 분포도 함께 확인하기 위해 size 속성값을 지정
[11]
sns.scatterplot(x=df['total_bill'], y=df['tip'], hue=df['sex'], size=df['size'])
<matplotlib.axes._subplots.AxesSubplot at 0x7f876a6b04d0>
출력
회귀선 (regplot)
개별 데이터 분포를 대표할 수 있는 하나의 선인 회귀선을 표시하는 그래프
[12]
sns.regplot(x=df['total_bill'], y=df['tip'])
<matplotlib.axes._subplots.AxesSubplot at 0x7f876a5dbfd0>
출력
- 5 -
회귀선만 표시하고 싶은 경우, scatter 속성을 False로 지정
[13]
sns.regplot(x=df['total_bill'], y=df['tip'], scatter=False)
<matplotlib.axes._subplots.AxesSubplot at 0x7f876a5f5e10>
출력
<matplotlib.axes._subplots.AxesSubplot at 0x7f876a4c8390>
출력
- 6 -
선 그래프 (lineplot)
선 그래프는 x축에 연도, 월, 일과 같은 시간을 사용한다면 시간에 따른 데이터 변화
추이를 쉽게 확인할 수 있다. 그렇기 때문에 선 그래프는 변수의 변화, 트렌드, 변화율
정보가 중요한 경우 사용한다.
[15] x = [1, 2, 3, 4, 5]
y = [10, 20, 25, 30, 42]
sns.lineplot(x=x, y=y)
<matplotlib.axes._subplots.AxesSubplot at 0x7f876a4a3650>
출력
[16]
sns.lineplot(x=df['size'], y=df['tip'])
<matplotlib.axes._subplots.AxesSubplot at 0x7f876a42e950>
출력
- 7 -
이번에는 앞의 그래프와 다르게 연한 배경이 함께 그려져있다. 이번 예제는 x축에 해
당하는 y축의 값이 여러 개 존재하기 때문에 값의 분포를 나타내는 부분이 함께 표시
된다. size가 2인 경우는 대부분 tip의 값이 표시된 직선 값에 수렵되는 반면, size가 5
인 경우에는 값의 편차가 큰 것을 확인할 수 있다.
<matplotlib.axes._subplots.AxesSubplot at 0x7f876a3bd410>
출력
- 8 -
막대 그래프 (barplot, countplot)
막대 그래프(barplot, countplot)는 수치를 막대의 길이로 표현해 시각화하는 그래프
앞서 선 그래프에서 그렸던 동일한 변수를 사용하여 막대 그래프를 그려보자.
[18]
sns.barplot(x=df['size'], y=df['tip'])
<matplotlib.axes._subplots.AxesSubplot at 0x7f876a3868d0>
출력
<matplotlib.axes._subplots.AxesSubplot at 0x7f876a1ca610>
출력
- 9 -
seaborn에서는 barplot과 모양은 유사하지만, y축의 값을 x축 변수의 개수(count)를 표
시하는 countplot도 제공한다. countplot은 y축은 개수를 표시하기 때문에 x축 변수만
지정한다.
[20]
sns.countplot(x=df['day'])
<matplotlib.axes._subplots.AxesSubplot at 0x7f876a1911d0>
출력
[21]
df['day'].value_counts()
Sat 87
Sun 76
출력 Thur 62
Fri 19
Name: day, dtype: int64
- 10 -
pointplot
pointplot은 막대 그래프에서 막대를 제외하고, 데이터의 평균값을 선으로 잇고 신뢰구
간을 함께 표시한 그래프
[22]
sns.pointplot(x=df['day'], y=df['tip'])
<matplotlib.axes._subplots.AxesSubplot at 0x7f876b9bed10>
출력
- 11 -
박스플롯(boxplot)
박스플롯(boxplot, 상자그림)는 막대 그래프와 유사하게 수치를 길이로 표현하지만, 사
분위수를 함께 시각화한다.
<matplotlib.axes._subplots.AxesSubplot at 0x7f876a4b12d0>
출력
- 12 -
바이올린플롯 (violinplot)
바이올린플롯은 박스플롯의 가장 큰 값과 작은 값을 모두 하나로 연결하여 하나의 도
형으로 표시한다. 그 모양의 가운데는 볼록하고 양 끝으로 갈수록 가늘어지는 형태를
띄어 바이올린 모양 같아서 바이올린플롯이라고 한다.
[24]
sns.violinplot(x=df['size'], y=df['tip'])
<matplotlib.axes._subplots.AxesSubplot at 0x7f876a025e10>
출력
- 13 -
히스토그램 (histplot)
히스토그램(histplot)은 변수의 분포를 막대형 그래프를 사용하여 표시하는 방법이다.
히스토그램은 x축에 계급을, y축에 빈도(도수)를 나타낸 뒤, 각 계급의 크기를 가로의
길이로, 빈도(도수)를 세로의 길이로 하는 직사각형을 차례로 그려서 표현한다. 막대 그
래프와 다르게 히스토그램은 가로축과 세로축이 연속형 자료이다.
[25]
sns.histplot(data=df['total_bill'])
<matplotlib.axes._subplots.AxesSubplot at 0x7f8769fc0250>
출력
[26]
sns.histplot(data=df['total_bill'], bins=5)
<matplotlib.axes._subplots.AxesSubplot at 0x7f8767eba650>
출력
- 14 -
[27]
sns.histplot(data=df['total_bill'], kde=True)
<matplotlib.axes._subplots.AxesSubplot at 0x7f8767e28a90>
출력
<matplotlib.axes._subplots.AxesSubplot at 0x7f8767d621d0>
출력
- 15 -
[29]
sns.countplot(x=df['day'])
<matplotlib.axes._subplots.AxesSubplot at 0x7f8767d45d50>
출력
히트맵 (heatmap)
히트맵(heatmap)은 여러 가지 변수를 한 번에 비교할 때 유용하게 사용하는 시각화 방
법으로, 2차원 격자 모양으로 나뉜 각각의 칸에 데이터의 값을 색상으로 표시한다.
출력
- 16 -
[31] #피봇 테이블의 값 연산을 변경하고 싶다면, aggfunc 속성을 지정하여 변경할 수 있다.
#최대값(max), 최소값(min), 합계(sum), 개수(count)
df.pivot_table('tip', 'day', 'size', aggfunc='count')
출력
[32]
sns.heatmap(pivot_df)
<matplotlib.axes._subplots.AxesSubplot at 0x7f8767c8a6d0>
출력
- 17 -
결측치를 0으로 변환하여 다시 히트맵을 확인해보자.
[33] pivot_df.fillna(0, inplace=True)
pivot_df
출력
[34]
sns.heatmap(pivot_df)
<matplotlib.axes._subplots.AxesSubplot at 0x7f87653c84d0>
출력
- 18 -
히트맵은 색상을 기반으로 값의 분포와 경향성을 파악하지만, 구체적으로 값을 확인할
수도 있다. heatmap의 annot 속성을 True로 지정하면 값을 함께 표시할 수 있다.
[35]
sns.heatmap(pivot_df, annot=True)
<matplotlib.axes._subplots.AxesSubplot at 0x7f8765304a50>
출력
- 19 -
20. 붓꽃 데이터 분석
붓꽃의 품종을 구분할 수 있도록 하는 열 데이터는 무엇일까?
[2]
sns.get_dataset_names()
['anagrams',
'anscombe',
'attention',
'brain_networks',
'car_crashes',
'diamonds',
'dots',
'exercise',
'flights',
출력 'fmri',
'gammas',
'geyser',
'iris',
'mpg',
'penguins',
'planets',
'taxis',
'tips',
'titanic']
- 1 -
[3] df = sns.load_dataset('iris')
df
출력
sepal_length : 꽃받침의 길이
sepal_width : 꽃받침의 너비
petal_length : 꽃잎의 길이
petal_width : 꽃잎의 너비
species : 품종
[4]
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 150 entries, 0 to 149
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 sepal_length 150 non-null float64
출력
1 sepal_width 150 non-null float64
2 petal_length 150 non-null float64
3 petal_width 150 non-null float64
4 species 150 non-null object
dtypes: float64(4), object(1)
memory usage: 6.0+ KB
- 2 -
[5]
df.describe()
출력
결측데이터 확인
[6]
df.isnull().sum()
sepal_length 0
sepal_width 0
petal_length 0
출력
petal_width 0
species 0
dtype: int64
[7]
df.isnull().sum().sum()
출력 0
- 3 -
중복데이터 확인
[8]
df.duplicated()[140:150]
140 False
141 False
142 True
143 False
144 False
출력 145 False
146 False
147 False
148 False
149 False
dtype: bool
출력 1
출력
- 4 -
[11]
df.loc[(df['sepal_length']==5.8) & (df['petal_width']==1.9), :]
출력
출력
출력
- 5 -
[14]
sns.heatmap(df.corr(), annot=True)
<matplotlib.axes._subplots.AxesSubplot at 0x7f117e04dbd0>
출력
품종의 분포 확인
[15]
df['species'].value_counts()
setosa 50
versicolor 50
출력
virginica 49
Name: species, dtype: int64
[16]
sns.histplot(x=df['sepal_length'], kde=True)
<matplotlib.axes._subplots.AxesSubplot at 0x7f117e0481d0>
출력
- 6 -
[17]
sns.histplot(x=df['sepal_width'], kde=True)
<matplotlib.axes._subplots.AxesSubplot at 0x7f117b111310>
출력
[18]
sns.histplot(x=df['petal_length'], kde=True)
<matplotlib.axes._subplots.AxesSubplot at 0x7f1179043950>
출력
- 7 -
[19]
sns.histplot(x=df['petal_width'], kde=True)
<matplotlib.axes._subplots.AxesSubplot at 0x7f1178f20390>
출력
<seaborn.axisgrid.FacetGrid at 0x7f1178f0c7d0>
출력
- 8 -
[21]
sns.displot(x=df['sepal_length'], hue=df['species'])
<seaborn.axisgrid.FacetGrid at 0x7f1178e26990>
출력
출력
- 9 -
나머지 3개 열 데이터는 한번에 그래프로 출력
출력
- 10 -
출력
- 11 -
[24]
sns.pairplot(df, hue='species', diag_kind='kde')
<seaborn.axisgrid.PairGrid at 0x7f59abdc2c90>
출력
- 12 -
21. 타이타닉 데이터 분석
타이타닉 승객의 데이터로 다양한 생존율 분포를 확인해보자.
데이터 확인하기
[2] import seaborn as sns
df_titanic = sns.load_dataset('titanic')
df_titanic.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 891 entries, 0 to 890
Data columns (total 15 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 survived 891 non-null int64
1 pclass 891 non-null int64
2 sex 891 non-null object
3 age 714 non-null float64
4 sibsp 891 non-null int64
5 parch 891 non-null int64
출력
6 fare 891 non-null float64
7 embarked 889 non-null object
8 class 891 non-null category
9 who 891 non-null object
10 adult_male 891 non-null bool
11 deck 203 non-null category
12 embark_town 889 non-null object
13 alive 891 non-null object
14 alone 891 non-null bool
dtypes: bool(2), category(2), float64(2), int64(4), object(5)
memory usage: 80.7+ KB
- 1 -
[3]
df_titanic.head()
출력
df_titanic.columns = column_t
[5]
df_titanic.head()
출력
- 2 -
[6]
df_titanic.head()
출력
[7]
df_titanic.describe(include='all')
출력
- 3 -
결측치 확인하기
[8]
df_titanic.isnull().sum()
생존여부 0
선실등급 0
성별 0
연령 177
형제및배우자수 0
부모및자녀수 0
요금 0
승선항코드 2
출력
선실등급명 0
남녀어린이구분 0
성인남성여부 0
데크번호 688
승선항 2
생존여부(y/n) 0
독신여부 0
dtype: int64
[9]
df_titanic.isnull().sum().sum()
출력 869
- 4 -
[11] import missingno as msno
msno.bar(df_titanic, figsize=(15, 5), color=(0.7, 0.2, 0.2))
출력
[12]
msno.matrix(df_titanic, figsize=(15, 5), color=(0.7, 0.2, 0.2))
출력
- 5 -
상관관계분석
[13]
df_titanic.corr()
출력
출력
- 6 -
목표 열인 '생존여부'와 상관계수가 높은 열은 '선실등급', '요금', '성인남성여부'이다. '
선실등급'과 '요금' 열의 상관계수는 -0.55이므로 매우 강한 음의 상관관계가 있다. 이
를 통해 객실등급에 따라 객실요금이 달라지는 것을 확인할 수 있다.
생존여부 (survived)
1 : 생존자
0 : 사망자
[15]
df_titanic['생존여부'].value_counts()
0 549
출력 1 342
Name: 생존여부, dtype: int64
[16]
sns.countplot(df_titanic['생존여부'])
출력
- 7 -
선실등급 (pclass)
[17]
sns.countplot(df_titanic['선실등급'])
출력
[18]
sns.countplot(df_titanic['선실등급'], hue=df_titanic['생존여부'])
출력
- 8 -
이번에는 barplot을 이용해 등급별 객실요금의 평균값을 본포를 알아보자. 생존자 비율
이 높은 1등석, 2등석을 보면 생존자들이 지불한 객실요금이 높은 패턴을 보인다.
[19]
sns.barplot(x=df_titanic['선실등급'], y=df_titanic['요금'], hue=df_titanic['생존여부'])
출력
성별 (sex)
[20]
df_titanic['성별'].value_counts()
male 577
출력 female 314
Name: 성별, dtype: int64
- 9 -
[21]
sns.histplot(x=df_titanic['성별'], hue=df_titanic['생존여부'], multiple='dodge')
출력
[22]
sns.histplot(x=df_titanic['성별'], hue=df_titanic['생존여부'], multiple='stack')
출력
- 10 -
multiple 속성에 fill을 설정하면 hue 속성의 상대적 비율을 백분율로 나타낸다.
[23]
sns.histplot(x=df_titanic['성별'], hue=df_titanic['생존여부'], multiple='fill')
출력
연령 (age)
[24]
df_titanic.loc[(df_titanic['연령'].isnull()) & (df_titanic['선실등급']==3), ['선실등급', '연령']]
출력
- 11 -
[25]
df_titanic.loc[(df_titanic['연령'].isnull()) & (df_titanic['선실등급']==2), ['선실등급', '연령']]
출력
[26]
df_titanic.loc[(df_titanic['연령'].isnull()) & (df_titanic['선실등급']==1), ['선실등급', '연령']]
출력
- 12 -
[27]
df_titanic.groupby('선실등급')['연령'].mean()
선실등급
1 38.233441
출력 2 29.877630
3 25.140620
Name: 연령, dtype: float64
[28]
df_titanic['연령'] = df_titanic.groupby('선실등급')['연령'].apply(lambda x: x.fillna(round(x.mean(),0)))
[29]
df_titanic.iloc[19, [1, 3]]
선실등급 3
출력 연령 25.0
Name: 19, dtype: object
[30]
df_titanic.iloc[181, [1, 3]]
선실등급 2
출력 연령 30.0
Name: 181, dtype: object
[31]
df_titanic.iloc[839, [1, 3]]
선실등급 1
출력 연령 38.0
Name: 839, dtype: object
- 13 -
형제및배우자수 (sibsp)
동승한 형제, 자매, 배우자수를 의미한다. boxplot으로 생존여부를 표시하면 동승자가
2 ~ 3명일 경우 생존여부에 차이가 있음을 알 수 있다.
[32]
sns.boxplot(x=df_titanic['형제및배우자수'], y=df_titanic['연령'], hue=df_titanic['생존여부'])
출력
- 14 -
부모및자녀수 (parch)
함께 탑승한 부모 및 자녀수를 의미한다. boxplot으로 생존여부와 함께 나이 분포를
그려보면, 동승자가 4명 이상일 경우, 생존자가 거의 없다는 것을 알 수 있다.
[33]
sns.boxplot(x=df_titanic['부모및자녀수'], y=df_titanic['연령'], hue=df_titanic['생존여부'])
출력
- 15 -
[34] # 승선 대표자를 고려해서 +1 을 해준다.
df_titanic['가족수'] = df_titanic['형제및배우자수'] + df_titanic['부모및자녀수'] + 1
df_titanic.head()
출력
[35]
sns.barplot(x=df_titanic['가족수'], y=df_titanic['생존여부'], hue=df_titanic['선실등급'])
출력
- 16 -
요금 (fare)
요금 열은 연속적인 값을 갖는다. displot의 kind 옵션을 kde로 설정하고 밀도함수 그
래프를 그려보자. 왼쪽으로 치우친 비대칭 구조를 보인다.
[36]
sns.displot(x=df_titanic['요금'], kind='kde', hue=df_titanic['생존여부'])
출력
비대칭 분포로 나타나서 요금이 높은 부분은 잘 파악이 안되고 있다. 비대칭 분포를
정규화하기 위해 로그 변환을 수행한다. 넘파이의 log1p 함수를 이용하여 '요금' 열에
로그를 취하면 분포 그래프가 아래와 같이 변하는 것을 확인할 수 있다.
- 17 -
[37] import numpy as np
df_titanic['요금로그'] = np.log1p(df_titanic['요금'])
sns.displot(x=df_titanic['요금로그'], kind='kde', hue=df_titanic['생존여부'])
출력
[38]
sns.stripplot(x=df_titanic['선실등급'], y=df_titanic['요금'], hue=df_titanic['생존여부'])
출력
- 18 -
[39]
sns.stripplot(x=df_titanic['선실등급'], y=df_titanic['요금로그'], hue=df_titanic['생존여부'])
출력
승선항코드 (embarked)
탑승항구를 나타내는 승선항코드 열은 결측값이 2개로 확인된다.
[40]
df_titanic.loc[df_titanic['승선항코드'].isnull(), :]
출력
S 644
C 168
출력
Q 77
Name: 승선항코드, dtype: int64
- 19 -
[42]
df_titanic['승선항코드'].mode()
0 S
출력
dtype: object
[43]
df_titanic['승선항코드'].mode()[0]
출력 ‘S’
[45]
df_titanic['승선항코드'].value_counts()
S 646
C 168
출력
Q 77
Name: 승선항코드, dtype: int64
- 20 -
barplot으로 탑승장소에 따른 생존율을 확인해보자.
[46]
sns.barplot(df_titanic['승선항코드'], y=df_titanic['생존여부'])
출력
- 21 -
22. 출생아수 분석
[1] # 설치 후 반드시 [런타임 다시 시작] 메뉴를 실행해주어야 함
!sudo apt-get install -y fonts-nanum
!sudo fc-cache -fv
!rm ~/.cache/matplotlib -rf
# 설치 메시지 일부 생략
Processing triggers for fontconfig (2.12.6-0ubuntu2) ...
출력
/root/.fontconfig: not cleaning non-existent cache directory
fc-cache: succeeded
출력 Mounted at /gdrive
[3]
drive_path = '/gdrive/My Drive/Colab/'
[4]
import pandas as pd
출력 (19, 865)
- 1 -
[6]
pd.options.display.max_columns = 865
[7]
df_kosis.head()
출력
[8] df = df_kosis.melt(id_vars='시군구별')
df.head()
출력
- 2 -
[9]
df['시군구별'].unique()
[10] print(df.shape)
df = df[df['시군구별'] != '시군구별'].copy()
print(df.shape)
(16416, 3)
출력
(15552, 3)
[11]
df['시군구별'].unique()
[12]
df.head()
출력
- 3 -
[13] df['연도'] = df['variable'].str.split('.', expand=True)[0]
df['월'] = df['variable'].str.split('.', expand=True)[1]
df['성별'] = df['variable'].str.split('.', expand=True)[2]
df.head()
출력
[14]
df.tail()
출력
[15]
df['성별'].unique()
- 4 -
[16]
df['성별'].nunique()
출력 2
[19]
df['성별'].value_counts()
전체 5184
남자 5184
출력
여자 5184
Name: 성별, dtype: int64
[20]
df.head()
출력
- 5 -
[21] df = df.rename(columns={'variable':'기간', 'value':'출생아수'})
df.head()
출력
[22]
df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 15552 entries, 1 to 16415
Data columns (total 6 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 시군구별 15552 non-null object
출력 1 기간 15552 non-null object
2 출생아수 15552 non-null object
3 연도 15552 non-null object
4 월 15552 non-null object
5 성별 15552 non-null object
dtypes: object(6)
memory usage: 850.5+ KB
- 6 -
[23] import numpy as np
df['출생아수'] = df['출생아수'].replace('-', np.nan)
df['출생아수'] = df['출생아수'].astype(float)
df['출생아수'].describe()
count 15012.000000
mean 3012.725286
std 6587.701782
min 30.000000
출력 25% 621.000000
50% 1025.000000
75% 1908.250000
max 63268.000000
Name: 출생아수, dtype: float64
출력
출력
- 7 -
[26] import seaborn as sns
import matplotlib.pyplot as plt
sns.set(font='NanumBarunGothic')
[27]
df_all.set_index(['연도', '월']).plot(figsize=(15,4))
<matplotlib.axes._subplots.AxesSubplot at 0x7f265bc67750>
출력
[28]
df_all[-48:].set_index(['연도', '월']).plot.bar(figsize=(15,4))
<matplotlib.axes._subplots.AxesSubplot at 0x7f265ab3c790>
출력
- 8 -
[29] plt.figure(figsize=(15,4))
sns.lineplot(data=df_all, x='연도', y='출생아수', ci=None)
<matplotlib.axes._subplots.AxesSubplot at 0x7f265b3919d0>
출력
[30] plt.figure(figsize=(15,4))
sns.lineplot(data=df_all, x='연도', y='출생아수', ci=None, hue='월')
<matplotlib.axes._subplots.AxesSubplot at 0x7f265a08cb50>
출력
[31] plt.figure(figsize=(15,4))
sns.barplot(data=df_all, x='연도', y='출생아수', ci=None)
<matplotlib.axes._subplots.AxesSubplot at 0x7f265ad86e90>
출력
- 9 -
[32] plt.figure(figsize=(15,4))
sns.barplot(data=df_all, x='연도', y='출생아수', ci=None, hue='월')
<matplotlib.axes._subplots.AxesSubplot at 0x7f2659fafcd0>
출력
출력
- 10 -
[34] plt.figure(figsize=(15,4))
sns.pointplot(data=df_local, x='연도', y='출생아수', hue='성별')
<matplotlib.axes._subplots.AxesSubplot at 0x7f2659a04d50>
출력
출력
[36] plt.figure(figsize=(15,4))
sns.pointplot(data=df_local_all, x='연도', y='출생아수')
<matplotlib.axes._subplots.AxesSubplot at 0x7f26595fa5d0>
출력
- 11 -
[37] plt.figure(figsize=(15,4))
sns.pointplot(data=df_local_all, x='연도', y='출생아수', hue='시군구별', ci=None)
plt.legend(loc='center right', bbox_to_anchor=(1.15, 0.5), ncol=1)
<matplotlib.legend.Legend at 0x7f26586928d0>
출력
출력
- 12 -
[39] plt.figure(figsize=(15,4))
sns.pointplot(data=df_local_2, x='연도', y='출생아수', ci=None, hue='시군구별')
<matplotlib.axes._subplots.AxesSubplot at 0x7f26596a29d0>
출력
출력
[41] plt.figure(figsize=(15,4))
sns.pointplot(data=df_sj, x='연도', y='출생아수', ci=None)
<matplotlib.axes._subplots.AxesSubplot at 0x7f2658274e50>
출력
- 13 -
[42] import numpy as np
plt.figure(figsize=(15,4))
sns.pointplot(data=df_sj, x='연도', y='출생아수', ci=None, estimator=np.sum)
<matplotlib.axes._subplots.AxesSubplot at 0x7f2657fe3190>
출력
- 14 -