🔥알림🔥
① 테디노트 유튜브 -
구경하러 가기!
② LangChain 한국어 튜토리얼
바로가기 👀
③ 랭체인 노트 무료 전자책(wikidocs)
바로가기 🙌
④ RAG 비법노트 LangChain 강의오픈
바로가기 🙌
⑤ 서울대 PyTorch 딥러닝 강의
바로가기 🙌
#03-Pandas(판다스) 데이터프레임(DataFrame) 조회, 정렬(sort), 조건필터(loc, iloc)
이번 에피소드에서는 Pandas 데이터프레임(DataFrame)의 가장 많이 사용하는 기능인 조회, 정렬 그리고 조건필터 입니다.
엑셀에서도 조회, 정렬, 조건필터의 기능을 가장 많이 활용합니다. 데이터를 정리, 분석할 때 이러한 기능 없이는 분석하기란 불가능에 가깝습니다.
Pandas는 조회, 정렬, 조건필터의 기능을 굉장히 편리하게 사용할 수 있도록 지원합니다. 조금씩 사용하다보면 매우 직관적이고 사용성도 어렵지 않습니다.
특히, loc
와 iloc
는 정말 많이 사용하는 기능이니 이번 기회에 손에 익혀 놓으시면 쏠쏠히 써먹으실 수 있습니다.
모듈 import
from IPython.display import Image
import numpy as np
import pandas as pd
import seaborn as sns
실습에 활용할 데이터셋
타이타닉: 탑승객의 사망자와 생존자 데이터 (seaborn 데이터셋 활용)
Image('https://static1.squarespace.com/static/5006453fe4b09ef2252ba068/t/5090b249e4b047ba54dfd258/1351660113175/TItanic-Survival-Infographic.jpg')
건조 당시 세계 최대의 여객선이었지만,1912년의 최초이자 최후의 항해 때 빙산과 충돌해 침몰한 비운의 여객선. 아마도 세상에서 가장 유명한 여객선이자 침몰선일 것입니다.
침몰한 지 100년이 넘었지만 아직까지 세계에서 가장 유명한 침몰선입니다.
사망자 수는 1위는 아니지만, 세계적으로 유명한 영화의 영향도 있고, 당시 최첨단 기술에 대해 기대감이 컸던 사회에 큰 영향을 끼치기도 한데다가, 근대 사회에서 들어서자마자 얼마 안된, 그리고 유명인사들이 여럿 희생된 대참사이기 때문에 가장 유명한 침몰선이 되었습니다. 또한 이 사건을 기점으로 여러가지 안전 조약들이 생겨났으니 더더욱 그렇습니다.
df = sns.load_dataset("titanic")
df.head()
컬럼 (column) 설명
- survivied: 생존여부 (1: 생존, 0: 사망)
- pclass: 좌석 등급 (1등급, 2등급, 3등급)
- sex: 성별
- age: 나이
- sibsp: 형제 + 배우자 수
- parch: 부모 + 자녀 수
- fare: 좌석 요금
- embarked: 탑승 항구 (S, C, Q)
- class: pclass와 동일
- who: 성별과 동일
- adult_male: 성인 남자 여부
- deck: 데크 번호 (알파벳 + 숫자 혼용)
- embark_town: 탑승 항구 이름
- alive: 생존여부 (yes, no)
- alone: 혼자 탑승 여부
데이터 분석!
주요 목표
- Pandas를 활용하여 타이타닉호 생존자, 사망자 데이터를 분석합니다.
- 데이터를 토대로 생존율이 높은 승객, 생존율이 낮은 승객은 누구인지 판단합니다.
head() 앞 부분 / tail() 뒷 부분 조회
- default 옵션 값으로 5개의 행이 조회됩니다.
- 괄호 안에 숫자를 넣어 명시적으로 조회하고 싶은 행의 갯수를 지정할 수 있습니다.
df.head()
df.tail()
df.head(10)
df.tail(10)
info()
- 컬럼별 정보(information)를 보여줍니다.
- 데이터의 갯수, 그리고 데이터 타입(dtype)을 확인할 때 사용합니다.
df.info()
object 타입은 쉽게 문자열이라고 생각하면 됩니다.
그런데, category 타입도 있습니다. category 타입은 문자열이지만, '남자' / '여자'처럼 카테고리화 할 수 있는 컬럼을 의미 합니다. 나중에 별도로 다루겠습니다.
describe()
- 각 컬럼에 대한 요약 통계 제공
- 수치형 컬럼 (numerical column)의 통계를 기본으로 보여 줍니다.
df.describe()
categorical column (문자열 컬럼)에 적용해 볼 수 없지 않습니다.
아래와 같이 include='object'
를 통해 categorical column에 대한 요약 통계를 확인할 수 있습니다.
df.describe(include='object')
value_counts()
column 별 값의 분포를 확인할 때 사용합니다.
남자, 여자, 아이의 데이터 분포를 확인하고 싶다면 다음과 같이 실행합니다.
df['who'].value_counts()
연습문제
embark_town
은 승객의 탑승 항구를 나타내는 column 입니다. 탑승 항구별 승객 데이터 분포를 확인해 주세요.
# 코드를 입력해 주세요
df['embark_town'].value_counts()
속성: Attributes
속성 값은 함수형으로 조회하지 않습니다.
자주 활용하는 DataFrame은 속성 값들은 다음과 같습니다.
- ndim
- shape
- index
- columns
- values
- T
차원을 나타냅니다. DataFrame은 2가 출력됩니다.
df.ndim
(행, 열) 순서로 출력됩니다.
df.shape
index는 기본 설정된 RangeIndex가 출력됩니다.
df.index
columns는 열을 출력 합니다.
df.columns
values는 모든 값을 출력하며, numpy array 형식으로 출력됩니다.
df.values
T: 전치 (Transpose) 는 Index와 Column의 축을 교환합니다.
df.T
타입 변환 (astype)
df.info()
int32
로 변경
df['pclass'].astype('int32').head()
float32
로 변경
df['pclass'].astype('float32').head()
object
로 변경
df['pclass'].astype('str').head()
category
로 변경.
category
로 변경시에는 Categories가 같이 출력 됩니다.
df['pclass'].astype('category').head()
정렬 (sort)
sort_index: index 정렬
- index 기준으로 정렬합니다. (기본 오름차순이 적용되어 있습니다.
- 내림차순 정렬을 적용하려면,
ascending=False
를 옵션 값으로 설정합니다.
df.sort_index().head(5)
df.sort_index(ascending=False).head(5)
sort_values: 값에 대한 정렬
- 값을 기준으로 행을 정렬합니다.
- by에 기준이 되는 행을 설정합니다.
- by에 2개 이상의 컬럼을 지정하여 정렬할 수 있습니다.
- 오름차순/내림차순을 컬럼 별로 지정할 수 있습니다.
df.sort_values(by='age').head()
내림차순 정렬: ascending=False
df.sort_values(by='age', ascending=False).head()
문자열 컬럼도 오름차순/내림차순 정렬이 가능하며 알파벳 순서로 정렬됩니다.
df.sort_values(by='class', ascending=False).head()
2개 이상의 컬럼을 기준으로 값 정렬 할 수 있습니다.
df.sort_values(by=['fare', 'age']).head()
오름차순/내림차순 정렬도 컬럼 각각에 지정해 줄 수 있습니다.
df.sort_values(by=['fare', 'age'], ascending=[False, True]).head()
Indexing, Slicing, 조건 필터링
df.head()
loc - indexing / slicing
- indexing과 slicing을 할 수 있습니다.
- slicing은 [시작(포함): 끝(포함)] 규칙에 유의합니다. 둘 다 포함 합니다.
indexing 예시
df.loc[5, 'class']
fancy indexing 예시
df.loc[2:5, ['age', 'fare', 'who']]
slicing 예시
df.loc[2:5, 'class':'deck'].head()
df.loc[:6, 'class':'deck']
loc - 조건 필터
boolean index을 만들어 조건에 맞는 데이터만 추출해 낼 수 있습니다.
condition = df['who'] == 'man'
condition
다음 2가지의 케이스로 조건에 맞는 데이터만 추출 할 수 있습니다.
결과는 같습니다.
케이스 1: df[condition]
df[condition].head()
케이스 2: df.loc[condition]
df.loc[condition].head()
다만, loc를 사용하는 것을 추천합니다. (값 대입시 issue 발생)
df[condition]['age']
df[condition]['age'] = 2
다음과 같은 경고 창이 뜹니다.
/home/ubuntu/anaconda3/envs/tensorflow2_p36/lib/python3.6/site-packages/ipykernel_launcher.py:1: SettingWithCopyWarning:
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead
See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
"""Entry point for launching an IPython kernel.
값을 대입하여 변경했음에도 불구하고 값이 변경 되지 않습니다.
df[condition]['age']
loc
를 사용하면 이러한 문제가 발생하지 않아 실수를 줄일 수 있습니다.
df.loc[condition, 'age'] = 10
df[condition].head()
loc - 다중 조건
다중 조건은 먼저 condition을 정의하고 & 와 | 연산자로 복합 조건을 생성합니다.
# 조건1 정의
condition1 = (df['fare'] > 30)
# 조건2 정의
condition2 = (df['who'] == 'woman')
df.loc[condition1 & condition2]
df.loc[condition1 | condition2]
연습문제
데이터를 다시 로드 합니다.
df = sns.load_dataset("titanic")
df.head()
1) 다음 조건을 만족하는 코드를 입력하세요.
- 나이가 30살 이상 남자 승객 조건 필터링
fare
를 많이 낸 순서로 내림차순 정렬- 상위 10개를 출력
# 코드를 입력해 주세요
condition1 = (df['age'] >= 30)
condition2 = (df['who'] == 'man')
df.loc[condition1 & condition2].sort_values(by='fare', ascending=False).head(10)
2) 다음 조건을 만족하는 코드를 입력하세요.
- 나이가 20살 이상 40살 미만인 승객
pclass
가 1등급 혹은 2등급인 승객- 열(column)은
survived
,pclass
,age
,fare
만 나오게 출력 - 10개만 출력
# 코드를 입력해 주세요
condition1 = (df['age'] >= 20) & (df['age'] < 40)
condition2 = (df['pclass'] < 3)
df.loc[condition1 & condition2, ['survived', 'pclass', 'age', 'fare']].head(10)
iloc
loc
와 유사하지만, index만 허용합니다.- loc와 마찬가지고, indexing / slicing 모두 가능합니다.
df.head()
indexing
df.iloc[1, 3]
fancy indexing
df.iloc[[0, 3, 4], [0, 1, 5, 6]]
slicing
df.iloc[:3, :5]
at
하나의 인덱스만 가져옵니다. loc
보다 속도가 빠르다는 장점은 있지만, 실질적인 효용성은 떨어집니다. 그냥 loc
를 사용해도 똑같은 결과를 얻을 수 있습니다.
%timeit df.loc[0, 'fare']
%timeit df.at[0, 'fare']
iat
하나의 인덱스만 가져옵니다. 속도가 빠르다는 장점은 있지만, 1개의 데이터만 조회 가능합니다. iloc
로 대체 사용가능합니다.
%timeit df.iloc[0, 5]
%timeit df.iat[0, 5]
where
DataFrame.where(cond, other=nan, inplace=False, axis=None, level=None, errors='raise', try_cast=False)
Pandas의 where
는 Numpy의 where
와 동작이 다릅니다.
- cond: True/False로 판단될 수 있는 식
- other: condition을 만족하지 못하는 요소에 할당 할 값
df.tail(5)
컬럼에 적용할 때
df['fare'].where(df['fare'] < 20, 0).tail(10)
행 전체에 적용할 때 (추천하는 정상적인 방법은 아닙니다)
df.where(df['fare'] < 20, 0).tail(10)
isin()
특정 값의 포함 여부는 isin 함수를 통해 비교가 가능합니다. (파이썬의 in 키워드는 사용 불가 합니다.)
sample = pd.DataFrame({'name': ['kim', 'lee', 'park', 'choi'],
'age': [24, 27, 34, 19]
})
sample
sample['name'].isin(['kim', 'lee'])
sample.isin(['kim', 'lee'])
loc
를 활용한 조건 필터링으로도 찰떡궁합입니다.
condition = sample['name'].isin(['kim', 'lee'])
sample.loc[condition]
댓글남기기