ilovechoonsik
[STARTERS 4기 TIL] 파이썬 전처리 베이스 (230208) 본문
📖 오늘 내가 배운 것
1. loc, iloc 사용한 데이터 추출
데이터 프레임에서 원하는 데이터 추출을 도와주는 고마운 녀석들
두 녀석의 가장 큰 차이점은 loc은 이름을 통한 추출, iloc은 번호(순서)를 통한 추출
헷갈릴 수 있으니 같이 정리
1.1 행 데이터 추출
loc | iloc | ||
df.loc[인덱스] | 시리즈 형태로 추출 | df.iloc[행번호] | 시리즈 형태로 추출 |
df.loc[인덱스리스트] | 데이터프레임 형태로 추출 | df.iloc[행번호리스트] | 데이터프레임 형태로 추출 |
df.loc[인덱스명슬라이스] | 행 전체 추출, 슬라이스 시에도 인덱스 이름 사용해야 함 | df.iloc[행번호슬라이스] | 슬라이스로 범위 지정 추출 |
# 인덱스가 i1,i3,i5인 행 추출 df.loc[['i1','i3','i5']] # 인덱스가 i3인 행을 데이터프레임 형태로 추출 df.loc[['i3']] # 인덱스가 i3인 행 이후의 모든 행 추출 df.loc['i3':] |
# 짝수 행번호의 데이터 추출 df.iloc[::2] # 홀수 행번호의 데이터 추출 df.iloc[1::2] # 1,3,5행 슬라이스 df.iloc[1:6:2] # 마지막 2개 행 추출하기(리스트) df.iloc[[-2,-1]] |
1.2 행, 열 데이터 추출
행 데이터 추출에서 사용했던 기법을 ,로 구분시켜 컬럼에 대해서도 사용가능
loc[인덱스명, 컬럼명] (리스트 및 슬라이싱도 가능)
iloc[인덱스 번호, 컬럼 번호] (리스트 및 슬라이싱도 가능)
loc | iloc | ||
# 인덱스 i1의 kor점수 df.loc['i1','kor'] # 인덱스 i1,i3,i5의 name, kor df.loc[['i1','i3','i5'],['name', 'kor']] # 모든 행에서 'name','math' 가져오기 df.loc[:,['name','math']] # 인덱스 i7 이후의 행에서 'name' 가져오기(데이터프레임) df.loc['i7':,['name']] |
# 0번째 행, 0번째 열 df.iloc[0,0] # 1,3,4번째 행 name, eng df.iloc[[1,3,4],[0,2]] # 1,3,5번째 행 0,2번째 열 슬라이싱 df.iloc[1:6:2, :3:2] # 마지막행 1,3열 슬라이싱 df.iloc[-1,1:4:2] # 모든행, 1,2열 df.iloc[:,[1,2]] |
2. 간단 시각화
2.1 3가지 그래프 간단하게 그려보기
import pandas as pd
import matplotlib.pyplot as plt
x = ['a','b','c','d','e']
y = [1,3,2,10,7]
# 순서대로 산점도, 막대, 선 그래프
plt.scatter(x,y,label='scatter')
plt.bar(x,y,label='bar')
plt.plot(x,y,label='plot')
# 제목 설정
plt.title('Test Graph', size=15)
# x,y축 라벨 설정
plt.xlabel('x')
plt.ylabel('y')
# 범례 표현 (그래프 함수 안에서 label=''로 설정)
plt.legend()
# 메시지 없이 그래프 표현
plt.show()
2.2 원하는 데이터를 막대그래프로 표현해 보기
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv('data/scores.csv')
df.head()
x = df['name']
y = df['kor']
plt.bar(x,y)
# x축 이름들 겹치지 않게 각도 설정
plt.xticks(rotation=90)
plt.title('Scores', size=20)
plt.xlabel('name')
plt.ylabel('kor_score')
plt.show()
3. 열과 행 추가/삭제/변경
3.1 열
표로 열과 행이 각각 어떤 경우에 어떤 함수 쓰는지 정리 -> append, rename, drop
사용법 | 예시 | |
열 추가 | df[column] = 추가할데이터 # 컬럼이 존재하면 추가, 존재하지 않으면 수정된다. |
# 학생 번호 추가하기 (1부터 시작하여 1씩 증가) df['no'] = range(1,len(df)+1) |
열 수정 | df[column] = 수정할데이터 | # 학생 번호 수정하기 (100부터 시작하여 1씩 증가) df['no'] = df['no']+99 |
열 삭제 | df.drop(columns=삭제할컬럼리스트, inplace=True) # 존재하지 않는 열은 삭제할 수 없다. |
# no, sum column 삭제 df.drop(columns=['no','sum'], inplace=True) |
컬럼명 한번에 수정 | df.columns = 컬럼명리스트 # 컬럼명리스트의 항목 수는 컬럼 수와 동일해야한다. |
#'이름','국어','영어','수학' df.columns=['이름','국어','영어','수학'] |
특정 컬렴명만 수정 | df.rename(columns={'현재컬럼명1':'바꿀컬럼명1','현재컬럼명2':'바꿀컬럼명2',...}) | # 이름-->성명 df = df.rename(columns={'이름':'성명'}) |
3.2 행
사용법 | 예시 | |
행 추가 후 인덱스 재지정 | df.append(추가할데이터, ignore_index=True) # 추가할 데이터는 딕셔너리 형태로 전달 : {컬럼1:값1, 컬럼2:값2,...} # 데이터프레임의 끝에 행 추가 # 기존 인덱스는 무시하고, 인덱스가 새롭게 생성된다. |
new_value = {'name':'Python','kor':80,'eng':90,'math':100} df = df.append(new_value, ignore_index=True) # ignore_index=True 기존 인덱스 무시하고 새로 생성하겠다는 뜻 |
인덱스 지정하여 추가/수정 | df.loc[인덱스] = 추가할데이터 df.loc[인덱스] = 수정할데이터 # 인덱스가 존재하면 해당 인덱스의 데이터가 수정된다. # 인덱스가 존재하지 않으면 데이터프레임의 끝에 데이터가 추가된다. |
# 인덱스 35에 추가 df.loc[35] = ['aaa',70,80,90] # 인덱스 30에 추 df.loc[30] = ['ccc',60,70,80] |
행 삭제 | df.drop(index=[삭제할인덱스리스트], inplace=True) | # 30,34,35 삭제 df.drop(index=[30,34,35], inplace=True) |
전체 인덱스명 변경 | df.index = 인덱스명리스트 인덱스명리스트의 항목 수는 인덱스 수와 동일해야한다. |
# range(100,3100,100) df.index = range(100,3100,100) |
특정 인덱스명 변경하 | df.rename(index={'현재컬럼명1':'바꿀컬럼명1','현재컬럼명2':'바꿀컬럼명2',...}) | # 100-->'a', 200-->'b' df.rename(index={100:'a',200:'b'}, inplace=True) |
4. 데이터에 함수 적용하기
4.1 함수로 컬럼의 데이터 변경하기
- 컬럼.apply(함수명)
- 컬럼.apply(함수명, 매개변수명=매개변수값)
매개변수명을 명시해주어야 한다. - 적용할 함수가 미리 정의되어 있어야 한다.
예시1
# 1. df['math']의 모든점수에 5점 더하기.(--> 105점?)
df_copy['math'] = df.math+5
df_copy
# 2. df['math']의 모든점수에 5점 더하기. 100점이 넘을 수 없다.
def plus5(x):
score = x+5
if score>=100:
score=100
return score
df_copy['math'] = df['math'].apply(plus5)
df_copy
# plus5의 매개변수 x는 df['math'] 데이터를 받는 매개변수!
# 때문에 apply 할 때는 함수명만 전달해주면 된다~
예시2
# 모든 점수에 n점 더하기. 100점이 넘을 수 없다.
def plusn(x,n):
score = x+n
if score>=100:
score=100
return score
# df['eng']의 모든 점수에 1점 더하기. 100점이 넘을 수 없다.
df_copy['eng'] = df['eng'].apply(plusn, n=1)
4.2 행/열 데이터 집계하기
- 데이터프레임.apply(함수명, axis=0) : 열단위로 함수가 적용된다.
- 데이터프레임.apply(함수명, axis=1) : 행단위로 함수가 적용된다.
# 합계 구하기
def get_sum(x):
return x.sum()
# 행, 열 단위 데이터가 들어오면 합계 구해서 return
행 단위 적용 - 학생 별 점수 합계
df_copy['sum'] = df.apply(get_sum, axis=1)
열 단위 적용 - 과목 별 점수 합계
df_copy.loc['sum'] = df.apply(get_sum, axis=0)
5. 결측치 다루기
5.1 결측치란?
NaN, 값이 없는 것! : 통계값을 구할 때 데이터의 개수에 영향을 끼치므로 적절한 처리 필요
5.2 결측치 확인 방법
df.isnull().sum() : 널값 개수
df.info() : 전체 정보
5.3 결측치 처리 방법
dropna() : 삭제
fillna() : 대치
방법 | 문법 | 예시 | |
결측치 삭제 | df.dropna() : 결측치가 존재하는 모든 행 삭제 df.dropna(axis=1) : 결측치가 존재하는 모든 열 삭제 |
||
결측치 대치 |
특정 값으로 | df.fillna(특정값) | df.fillna(0) -> 전부 0 으로 |
이전 값으로 | df.fillna(method='ffill') | 이전 값 없으면 대치 X, 그대로 NaN | |
다음 값으로 | df.fillna(method='bfill') | 다음 값 없으면 대치 X, 그대로 NaN | |
컬럼별로 대치할 값 지정 | df.fillna({'컬럼명1':값1, '컬럼명2':값2,...}) | df.fillna({'A':0,'B':1,'C':2,'D':3}) |
📌 결측치가 포함된 데이터의 통계값?
- 결측치는 없는 데이터로 간주된다.
df['A'].mean() # 3.0
df['B'].mean() # 3.0
6. 판다스 자료형
6.1 자료형 종류
int64 : 정수형
float64 : 실수형
bool : 부울형
object : 문자열
category : 카테고리
datetime64 : 날짜, 시간
# 샘플데이터
df = pd.DataFrame({'float': [1.0, 2.0],
'int': [1,2],
'datetime': [pd.Timestamp('20200101'),pd.Timestamp('20210101')],
'string': ['a','b'],
'bool':[True,False],
'object':[1,'-'], # 정수 + 문자 혼합
'float2' : [1.0, 2]}) # 정수 + float = float
6.2 자료형 처리
방법 | 문법 | 예시 |
자료형 확인 | 데이터프레임 : df.dtypes 시리즈 : series.dtype 시리즈 데이터 타입 혼합 -> object 시리즈 정수와 실수 혼합 -> float64 |
시리즈의 경우 : df['int'].dtype 혼합의 경우 : type(df.loc[행,열]) |
자료형 변환 | df.astype('자료형') series.astype('자료형') |
전체 자료형 변환 : df = df.astype('자료형') object에서 int로 : df = df.astype('float').astype('int') object인 데이터를 바로 int로 바꾸는 건 불가능! float으로 바꾸고 int로 넘긴다 특정 컬럼의 자료형 변환 : df['col'] = df['col'].astype('자료') |
# 숫자형으로 변환 | pd.to_numeric(col, errors='ignore') : 숫자로 변경할 수 없는 값이 있으면 작업하지 않음 pd.to_numeric(col, errors='coerce') : 숫자로 변경할 수 없는 값이 NaN으로 설정 pd.to_numeric(col, errors='raise') : 숫자로 변경할 수 없는 값이 있으면 에러발생(default) |
- pd.to_numeric(s2, errors='ignore') 0 1.0 1 2 2 a dtype : object - pd.to_numeric(s2, errors='coerce') 0 1.0 1 2.0 3 NaN dtype : float64 |
# 시계열 데이터로 변환 | pd.to_datetime(col) | - astype df['출생'] = df['출생'].astype('datetime64') - to_datetime df['사망'] = pd.to_datetime(df['사망']) |
👻 자료형이 혼합된 컬럼의 자료형 변환
# col3 컬럼을 str형으로 변환
df['col3'] = df['col3'].astype('str')
type(df.loc[0,'col3'])
#str
# 변경할 수 없는 자료가 섞여있으면 error
df['col3'] = df['col3'].astype('int')
#error
6.3 카테고리형 자료 다루기
(1) 카테고리형?
특정 값들로만 이루어지는 자료형! 범주형 데이터를 다룬다.
ex) 성별, 혈액형, 학점, 지역
# 범주형 자료란? 관측 결과가 몇 개의 범주 또는 향목의 형태로 나타나는 자료를 말한다.
(2) 카테고리형 다루기
목적 | 사용법 | 예시 |
카테고리형으로 변환 | 컬럼.astype('category') | # 자료형 변환하기 df['grade'] = df['grade'].astype('category') |
카테고리 요소 이름 바꾸기 | 컬럼.cat.categories = 카테고리리스트 | # 1234 등급을 ABCD로 df['grade'].cat.categories = ['A','B','C','D'] |
카테고리 추가 | 컬럼.cat.set_categories(카테고리리스트) | # F 끼워넣기 df['grade'] = df['grade'].cat.set_categories(['A','B','C','D','F']) |
데이터 용량을 절약할 수 있다는 장점!
6.4 시계열 자료 다루기
(1) 시계열 데이터?
Pandas에서 날짜와 시간을 다루는 자료형
목적 | 사용법 | 예시 |
컬럼을 datetime 자료형으로 변경 | pd.to_datetime(컬럼) | # 출생, 사망 컬럼을 datetime 자료형으로 변경하기 df['출생'] = pd.to_datetime(df['출생']) |
연, 월, 일 분기 추출 | 컬럼.dt.year 컬럼.dt.month 컬럼.dt.day 컬럼.dt.quarter |
year : 1962, 1953 ... month : 1, 2, 3 ... day : 20, 21 ... quarter : 1,2,3,4 |
날짜 계산 | 긴 날짜 - 짧은 날 | # 연산 시 최소 단위로 결과값 반환 df['생존일수'] = df['사망']-df['출생'] : 24213 days # 생존기간 컬럼 만들기 df['생존기간'] = df['사망'].dt.year-df['출생'].dt.year : 56 |
요일, 월이름 추출 | 컬럼.dt.strftime('%a') : 요약된 요일이름 컬럼.dt.strftime('%A') : 긴 요일이름 컬럼.dt.strftime('%w') : 숫자요일(0:일요일) 컬럼.dt.strgtime('%b') : 요약된 월이름 컬럼.dt.strftime('%B') : 긴 월이름 |
%a : Thu, Fri ... %b : Jan, Feb ... |
datetime 자료형을 인덱스로 만들어 사용 | df.index = df['컬럼'] | # 출생 컬럼을 인덱스로 만들기 df.index = df['출생'] |
# 1955년 출생한 사람 데이터 추출하기
df.loc['1955']
# 1955년 2월 출생한 사람 데이터 추출하기
df.loc['1955-02']
7. 데이터 프레임 합치기 (concat, merge)
7.1 데이터프레임 연결하기 concat
- pd.concat(데이터프레임리스트)
데이터프레임이 동일한 컬럼명 기준으로 행으로 연결된다. - pd.concat(데이터프레임리스트, axis=1)
데이터프레임이 동일한 인덱스 기준으로 열로 연결된다.
예시 | |||
행으로 연결하기 |
|||
df1 | df2 | df3 | |
합칠 테이블 | ![]() |
![]() |
![]() |
1. 컬럼명 기준으로 연결 | 2. 공통된 컬럼만 남기기 (join='inner') |
3. 인덱스 재지정 (ignore_index=True) |
|
concat 예시 | pd.concat([df1,df2,df3]) ![]() |
pd.concat([df1,df2,df3], join='inner') ![]() |
pd.concat([df1,df2,df3], join='inner', ignore_index=True) ![]() |
열로 연결하기 |
|||
df4 | df5 | df6 | |
합칠 테이블 | ![]() |
![]() |
![]() |
1. 인덱스 기준으로 연결 | 2. 공통된 인덱스 남기기 | ||
pd.concat([df4,df5,df6], axis=1)![]() |
pd.concat([df4,df5,df6], axis=1, join='inner') ![]() |
7.2 공통된 열 기준으로 연결하기 merge
- pd.merge(left,right,on=기준컬럼,how=연결방법)
- 2개의 데이터프레임을 연결한다.
예시 | ||
df7 | df8 | |
합칠 테이블 | ![]() |
![]() |
1. 공통 데이터만으로 연결 how='inner' (default) |
2. 모든 행 연결 how='outer' |
|
merge 예시 | pd.merge(df7, df8, on='name', how='inner')![]() |
pd.merge(df7, df8, on='name', how='outer')![]() |
3. 왼쪽 데이터프레임 기준으로 연결 how='left' |
4. 오른쪽 데이터프레임 기준으로 연결 how='right' |
|
pd.merge(df7, df8, on='name', how='left')![]() |
pd.merge(df7, df8, on='name', how='right')![]() |
8. 행/열 형태 변경 (melt, pivot)
8.1 행을 열로(값으로) 보내기! melt
- 데이터프레임.melt()
- pd.melt(데이터프레임)
melt 예시 | |||
예제 테이블 | ![]() |
||
1. 모든 열 melt df.melt( ), pd.melt(df) |
2. 고정할 컬럼 지정하여 melt id_vars=[열이름리스트] --> 위치를 그대로 유지할 열 이름 |
||
![]() |
# name, kor 고정 df.melt(id_vars=['name','kor']) ![]() |
||
melt 예시 | 3. 행으로 위치를 변경할 열 지정 value_vars=[열이름리스트] |
4. 컬럼명 변경 var_name=컬럼명 --> value_vars로 위치를 변경한 열 이름 value_name=var_name으로 위치를 변경한 열의 데이터를 저장한 열 이름 |
|
# kor, eng df.melt(id_vars='name', value_vars=['kor','eng']) ![]() |
# subject, score df.melt(id_vars='name', value_vars=['kor','eng'], var_name='subject', value_name='score') ![]() |
8.2 열을 행으로 보내기! pivot
- df.pivot( index=인덱스로 사용할 컬럼, columns=컬럼으로 사용할 컬럼, values=값으로 사용할 컬럼 )
샘플데이터 생성
# 샘플데이터
df = pd.read_csv('data/scores.csv')
df = df.head(2)
df = df.melt(id_vars = 'name', var_name='subject',value_name='score')
def get_grade(x):
if x>=90: grade='A'
elif x>=80: grade='B'
elif x>=70: grade='C'
elif x>=60: grade='D'
else: grade='F'
return grade
df['grade'] = df['score'].apply(get_grade)
df = df.sort_values('name')
df
예시 1. 인덱스=name, 컬럼=subject, values=score
df.pivot(index='name', columns='subject',values='score')
예시 2. 인덱스=name, 컬럼=subject, valyes=[score, grade]
df.pivot(index='name', columns='subject',values=['score','grade'])
8.3 행과 열 바꾸기
df.transpose()
9. 데이터 집계하기(pivot, groupby)
9.1 pivot_table 데이터 집계
- 피벗테이블은 표의 데이터를 요약하는 통계표이다.
- pd.pivot_table(데이터프레임, index=인덱스, columns=컬럼, values=집계할데이터, aggfunc=통계함수)
- aggrunc의 디폴트는 mean
사용 데이터
# 샘플데이터
df = pd.DataFrame({"item": ["shirts", "shirts", "shirts", "shirts", "shirts",
"pants", "pants", "pants", "pants"],
"color": ["white", "white", "white", "black", "black",
"white", "white", "black", "black"],
"size": ["small", "large", "large", "small",
"small", "large", "small", "small",
"large"],
"sale": [1, 2, 2, 3, 3, 4, 5, 6, 7],
"inventory": [2, 4, 5, 5, 6, 6, 8, 9, 9]})
# item, size별 재고 합계
df.pivot_table(index='item', columns='size',values='inventory' ,aggfunc='sum')
# [item,color], size별 재고 합계
df.pivot_table(index=['item','color'],columns='size', values='inventory', aggfunc='sum')
NULL 0처리는? fill_value=0 추
# [item,color], size별 판매,재고 합계
df.pivot_table(index=['item','color'], columns=['size'], values=['sale','inventory'], aggfunc='sum')
9.2 groupby 데이터 집계
- df.groupby(그룹기준컬럼).통계적용컬럼.통계함수
- count() : 누락값을 제외한 데이터 수
- size() : 누락값을 포함한 데이터 수
- mean() : 평균
- sum() : 합계
- std() : 표준편차
- min() : 최소값
- max() : 최대값
- sum() : 전체 합
(1) 그룹에 사용자 정의함수 적용하기
- df.groupby(그룹기준컬럼).통계적용컬럼.agg(사용자정의함수,매개변수들)
def my_mean(values):
return sum(values)/len(values)
df.groupby(['Sex','Pclass']).Survived.agg(my_mean)
(2) 그룹 오브젝트 출력하기
- 데이터프레임.groupby(그룹기준컬럼).groups --> 그룹별 인덱스:[데이터리스트] 출력
- 데이터프레임.groupby(그룹기준컬럼).get_group(그룹인덱스) --> 그룹별 인덱스에 해당하는 데이터프레임 출력
# Pclass 그룹별 인덱스
df20.groupby('Pclass').groups
#{1: [1, 3, 6, 11], 2: [9, 15, 20, 21], 3: [0, 2, 4, 7, 8, 10, 12, 13, 14, 16, 18, 22]}
🚨 Pclass 그룹 출력(1등석)
df20.groupby('Pclass').get_group(1)
🚨 Pclass 그룹 출력(2등석)
df20.groupby('Pclass').get_group(2)
#유데미, #유데미코리아, #유데미부트캠프, #취업부트캠프, #부트캠프후기, #스타터스부트캠프, #데이터시각화 #데이터분석 #태블로
'STARTERS 4기 🚉 > TIL 👶🏻' 카테고리의 다른 글
[STARTERS 4기 TIL] 데이터 시각화 #2 (230213) (0) | 2023.02.13 |
---|---|
[STARTERS 4기 TIL] 데이터 시각화 (230210) (0) | 2023.02.10 |
[STARTERS 4기 TIL] 공공 데이터 분석 (230209) (0) | 2023.02.09 |
[STARTERS 4기 TIL] 파이썬 기초 + 판다스, 시리즈 (230207) (0) | 2023.02.07 |
[STARTERS 4기 TIL] 파이썬 기초 (230206) (0) | 2023.02.07 |