티스토리 뷰

반응형

항상 시작은 CRISP-DM

과제를 수행할 때 기본 프로세스 - 이 방법론의 기초에서 일을 하게 될 가능성이 높다.

 

비지니스 이해 <-> 데이터 이해 -> 데이터 평가 <-> 모델링 -> 평가 -> 배포

 

평가 -> 비지니스 이해

 

비지니스 이해 단계는 문제를 정의하는 단계.

회사에서 무엇을 기대하는 가? 회사의 문제를 해결하는 지를 기대하는 것이다.

데이터 분석, 모델링을 가지고 문제를 해결하는 것

 

1단계 데이터 분석

 

기본 구조가 2차원 수치하고 범주

기본 분석 단위 - 행

 

범주는 그룹을 짓는 것 - 공통된 특징

x : feature 독립변수

y : target, label 종속변수

 

분석 단위 : 샘플,관측치, 인스턴스(헷갈릴 수 있다), data point

 

한 행이 시간 단위로 쌓여있어야 한다.

 

numpy 수치 연산, pandas 비지니스 모델링

 

loc,groupby는 꼭 알아둬러.

 

데이터 전처리

데이터 천처리에는 두 가지 단계

 

1. 분석을 위한 데이터 구조 만들기

2. 모델링을 위한 전처리

 

SQL을 더 배워야 한다.

 

목표

1. 분석을 위한 데이터 구조를 이해하고 생성할 수 있다.

2. 데이터 분석 절차를 이해하고 분석 도구를 사용할 수 있다.

 

데이터프레임 변경

 

  • 열 이름 변경
  • 열 추가
  • 열 삭제
  • map,cut

 

열 추가와 열 삭제는 반드시 알아야 한다.

 

열 이름 변경

columns 속성 변경 : 모든 열 이름 변경

tip.columns =[ '컬럼명1','컬럼명2'....]

그런데 너무 길다.

rename() 메소드 사용 : 지정한 열 이름 변경

tip.rename(columns = {컬럼명: 새로 변경할 이름 ,inplace=True} 딕셔너리

 

inplace가 없으면 수정한 것처럼 조회한다.

inplace를 true로 해야 원본 바뀐다.

 

열 추가

de[추가할 컬럼명] = de[수치형 컬럼명] / de[수치형 컬럼명2] * 100

 

없는 열을 변경하면 그 열이 맨 뒤에 열이 추가된다.

titanic['col3'] = titanic['col1']+ titanic['col2']

 

지정한 위치에 열을 추가하기 위해서는, insert() 메소드를 사용하면 된다.

 

df.insert(넣을 인덱스 자리, 추가할 컬럼명, 수치연산)

titanic.insert(1, 'col3', titanic['col1']+ titanic['col2'])

 

열 삭제

 

drop() 메소드를 사용해 열 삭제

axis=0 행 삭제

axis=1 열 삭제

여기도 inplace

 

열 두 개 삭제하려면 리스트로 입력받는다.

titanic.drop( ['컬럼1','컬럼2'], axis=1, inplace=True)

 

만약 작년 급여를 계산하려면, 올해 급여/ (1+ 인상률 /100)

그걸 계산하면 된다.

 

data['컬럼명'].value_counts()

 

np.where로 해당 조건 값을 변경하고 추가할 수 있다.

da['Job'].value_counts()

da['Job']=np.where(data['Job']>2,'sat','unsat')

 

삭제하기 전에는 돌리기 어려우므로, .copy를 이용하여 백업을 만들어 놓는다.

여러 열을 삭제할 떄는 리스트로 묶어준다.

da2.drop('In', axis=1, inplace=True)
da2.drop(['In','Out'],axis=1, inplace=True)

 

값 변경

값을 변경할 때는 해당 값을 주면 전체 행에 해당 값이 들어간다. 

da['In'] = 0

 

조건에 의한 값을 변경하려면 loc을 사용하면 된다.

da.loc['In'>20, 'In'] =0

 IN이 20보다 클때, IN이라는 컬럼에서 0으로 만든다는 뜻이다.

 

np.where로도 값 변경이 가능하다. 다만, 이때는 인덱스 값이므로 따로 할당해줘야 한다.

da['IN'] = np.where(da['IN']>20,da['IN'],0)

원래 있던 값으로 유지하고 싶을 경우, 위처럼 넣어주면 된다.

 

map, cut 메소드

map은 파이썬의 map 함수와 유사하다.

각 값을 map의 매개변수를 실행한 값을 넣어준다.

실행함수는 딕셔너리 형태로 넣어준다.

data['G'] = data['G'].map({'M': 1, 'F': 0})

 

cut은 숫자형 변수를 범주형 변수로 만드는 데 유용하다.

 

나이를 연령대로, 구매액을 등급으로, 한마디로 구간을 나눠주는 함수.

균등분할할 수도 있고, 구간을 지정해줘서 분할할 수도 있다.

a_group = pd.cut(da2['A'], 3) #균등 분할
a_group2 = pd.cut(da2['A'], 3, labels = ['a','b','c']) #균등 분할 후에 이름을 붙인다

 

원하는 구간으로 나누려면, bins=[]를 따로 지정해줘야 한다.

a_group2 = pd.cut(da2['A'], bins =[0, 40, 50, 100] , labels = ['y','j','s'])

 

이것이 최종 형태이다.

당연하지만, bins의 개수 -1이 label의 개수이다.

cut을 하고 a.value_counts()를 했을 때,

() 은 <나 >을 의미하고, []은 <=나 >=를 의미한다.

 

cut으로 나누면, ](<=) , ( ], ( ], (

이런식으로 나눠진다.

 

값의 범위 중 오른쪽(큰값)이 아닌 왼쪽(작은값)이 포함되도록 하려면 pd.cut 함수 옵션에 right = False 라고 지정

 

cut으로 나온 결과는 시리즈로 나오므로, 다시 데이터프레임에 넣거나 추가할 수도 있다.

 

데이터 프레임의 결합

contcat, merge, pivot

 

pd.concat : 인덱스(행), 칼럼 이름(열) 기준으로 결합

 

pd.merge() : 매핑 기준은 특정 키 기준으로 결합.

 

pd.concat

concat은 붙이는 것이다. axis=0은 위아래로 붙이는 것 칼럼 이름 기준.

axis=1은 옆으로 붙이는 것.

 

Join 방법

Outer : 모든 행과 열 합치기 (기본값) - 모든 행은 유지하고, 없는 건 NaN -> FULL OUTER JOIN

Inner : 같은 행과 열만 합치기(같은 컬럼 이름이 있는 놈들만 합친다.)

 

axis=1일 때는 행 인덱스가 기준이 된다.

왼쪽에서 오른쪽으로 붙인다.

 

컬럼 이름이 같아도 붙을 수 있다. 이름을 좀 변경시켜줘야 헷갈리지 않는다.

pd.concat([dataframe1, dataframe2], axis = 0, join = 'inner')

 

위아래로 붙였을 떄는 인덱스 리셋을 해야 한다.

 

s1 = sa1.groupby('Date')['Qty'].agg(qty1 = 'sum')

 

agg에서 컬럼명을 지정할 때는 컬럼명 = 집계함수 이렇게 하면 된다.

 

merge

판다스에서 조인은 어떠한 컬럼의 값이 같을 때 다른 값들로 채워넣고 싶을 때 사용한다.

 

지정한 칼럼의 값을 기준으로 병합한다.

옆으로만 병합한다.

 

어떤 칼럼을 기준으로 삼을지를 고심해야 한다. 예제는 A를 기준으로 삼았을 떄의 merge

 

inner : 같은 값만(A를 기준으로 삼으면, A가 같은 행만 출력)

outer : 모두(모든 행을 유지하고, 없는 행은 Nan)

left : 왼쪽 df는 모든 행 유지, 오른쪽 df는 A가 같은 값만 -> Left Outer JOIN

right : left의 반대. Right Outer JOIN

pd.merge(df1,df2, how='방법', on='어떤 컬럼을 기준으로 할지')
pd.merge(df1,df2, how='inner', on='A')

 

만약 on에 같은 컬럼이 없으면 에러가 난다.

inner는 on만 쓰면 되지만, 나머지는 left_on, right_on으로 써줘야 한다.

 

left_on은 

 

한번에 여러 개의 데이터프레임을 결합하고 싶을 땐 다음과 같이 사용

from functools import reduce

reduce(lambda x,y: pd.merge(x,y, on='Col1', how='outer'), [df1, df2, df3])

 

from functools import reduce

s_mer = reduce(lambda x,y: pd.merge(x,y, on='qty', how='inner'), [s1, s2, s5,s11])

 

집계 후 열 이름 변경하려면, rename이나 columns를 사용한다.

s1 = s1.groupby('Date',as_index=False)['Q'].agg('sum')
s1.columns =['Date','Q1']

as_index=False를 써야 merge의 기준이 되는 date가 나오므로 반드시 써줄 것.

 

s_mer = reduce(lambda x,y: pd.merge(x,y, on='Date', how='outer'), [s1, s2, s5,s11])

date가 기준이므로 행이 똑같아 옆으로 붙여진다.

 

만약에 이름을 바꾸지 않고, Qty를 기준으로 한다면 아래로 붙여진다.

left_on,right_on은 칼럼 이름이 다를 때 같다고 지정해주고 싶을 때 쓴다.

 

만약에 컬럼이 다른 데이터프레임에 각각 있다면?

1. merge를 먼저 하고,

2. 그 다음에 groupby로 묶는다.

all= pd.merge(s1,pro,how='inner',on='Pro_ID') #먼저 merge를 하고
s11 = all.groupby('Date',as_index=False)['Q'].agg('sum') #각각에 대해 합계를 구해본다.
c11 = all.groupby('Cat'as_index=False)['Q'].agg('sum')

all= pd.merge(s1,pro) #아무것도 안 넣으면 자동으로 inner가 된다.

 

이렇게 데이터 프레임을 묶어서 집계를 볼 수 있다.

 

pivot

결합은 아니지만 집계 후 데이터프레임을 변형해서 조회하는 데 종종 사용한다.

tmp = pd.merge(s1, pro)
tmp2 = temp.groupby(['Date', 'Cat'], as_index = False)['Q'].sum()
tmp3 = tmp2.pivot(index= 'Cat', columns='Date' ,values='Q')

 

일별, 카테고리별 판매량을 집계한 후에, pivot으로 만들 수도 있다.

index=행, columns=열, values=값이다.

 

노하우 

데이터 집계를 위해서는 일단 테이블들을 merge를 한 후에 찾는걸 추천한다.

그래야만 groupby로 묶을 수 있기 때문이다.

 

temp라는 변수로 일단 다 묶어두고, 집계값만 이름을 달리하여 계속해서 재사용한다.

state_qty=temp2.groupby('St',as_index=False)['A'].sum()
state_qty.sort_values(by='A',ascending=False).head(3)

 

sort_values를 사용하면, 최대 값 추출도 깔끔하게 만들 수 있다.

 

반응형