반응형
* 위 강의노트는 패스트캠퍼스에서 주관하는 강의를 수강하고 작성한 노트입니다.
1. DataFrame group by 이해하기¶
In [1]:
import pandas as pd
import numpy as np
group by¶
- 아래의 세 단계를 적용하여 데이터를 그룹화(groupping) (SQL의 group by 와 개념적으로는 동일, 사용법은 유사)
- 데이터 분할
- operation 적용
- 데이터 병합
In [21]:
# data 출처: https://www.kaggle.com/hesh97/titanicdataset-traincsv/data
df = pd.read_csv('./train.csv')
df.head()
Out[21]:
GroupBy groups 속성¶
- 각 그룹과 그룹에 속한 index를 dict 형태로 표현
In [3]:
class_group = df.groupby('Pclass') ## groupby 객체 만들기
class_group
Out[3]:
In [4]:
class_group.groups
Out[4]:
In [6]:
gender_group = df.groupby('Sex') ## groupby 객체 만들기
gender_group.groups
Out[6]:
groupping 함수¶
- 그룹 데이터에 적용 가능한 통계 함수(NaN은 제외하여 연산)
- count - 데이터 개수
- sum - 데이터의 합
- mean, std, var - 평균, 표준편차, 분산
- min, max - 최소, 최대값
In [7]:
class_group.count()
Out[7]:
In [8]:
class_group.sum()
Out[8]:
In [10]:
class_group.mean()['Survived'] # Column 따로 구하기
Out[10]:
In [11]:
class_group.max()
Out[11]:
- 성별에 따른 생존율 구해보기
In [12]:
df.groupby('Sex').mean()['Survived']
Out[12]:
복수 columns로 groupping 하기¶
- groupby에 column 리스트를 전달
- 통계함수를 적용한 결과는 multiindex를 갖는 dataframe
- 클래스와 성별에 따른 생존률 구해보기
In [14]:
df.groupby(['Pclass', 'Sex']).mean()['Survived']
Out[14]:
In [15]:
df.groupby(['Pclass', 'Sex']).mean().loc[(2, 'female')]
Out[15]:
index를 이용한 group by¶
- index가 있는 경우, groupby 함수에 level 사용 가능
- level은 index의 depth를 의미하며, 가장 왼쪽부터 0부터 증가
- set_index 함수
- column 데이터를 index 레벨로 변경
- reset_index 함수
- 인덱스 초기화
In [18]:
df.set_index(['Pclass']) # 인덱스초기화
Out[18]:
In [19]:
df.set_index(['Pclass', 'Age']) # 멀티인덱스
Out[19]:
In [21]:
df.set_index(['Pclass', 'Age']).reset_index()
Out[21]:
In [22]:
df.set_index('Age').groupby(level = 0).mean() # setindex후 0번째로 groupby
Out[22]:
나이대별로 생존률 구하기¶
In [23]:
import math
def age_categorize(age):
if math.isnan(age):
return -1
return math.floor(age/10) * 10
In [24]:
# age groupby
df.set_index('Age').groupby(age_categorize).mean()
Out[24]:
MultiIndex를 이용한 groupping¶
In [26]:
df.set_index(['Pclass', 'Sex']).groupby(level = [0, 1]).mean()
Out[26]:
aggregate(집계) 함수 사용하기¶
- groupby 결과에 집계함수를 적용하여 그룹별 데이터 확인 가능
In [27]:
df.set_index(['Pclass', 'Sex']).groupby(level = [0, 1]).aggregate([np.mean, np.sum, np.max])
Out[27]:
2. Transform 함수의 이해 및 활용하기¶
transform 함수¶
- groupby 후 transform 함수를 사용하면 원래의 index를 유지한 상태로 통계함수를 적용
- 전체 데이터의 집계가 아닌 각 그룹에서의 집계를 계산
- 따라서 새로 생성된 데이터를 원본 dataframe과 합치기 쉬움
In [3]:
df.groupby('Pclass').mean() ## 그룹별 평균
Out[3]:
In [4]:
df.groupby('Pclass').transform(np.mean) #원본의 인덱스를 유지한채로 각 그룹별 mean을 적용
Out[4]:
In [5]:
df['Age2'] = df.groupby('Pclass').transform(np.mean)['Age']
df
Out[5]:
In [9]:
df[df['Pclass'] == 2]['Age2'] ## 전부 동일
Out[9]:
In [10]:
## 다중 그룹핑 사용
df['Age3'] = df.groupby(['Pclass', 'Sex']).transform(np.mean)['Age']
df.head()
Out[10]:
3. pivot, pivot_table 함수의 이해 및 활용¶
In [24]:
df = pd.DataFrame({
'지역': ['서울', '서울', '서울', '경기', '경기', '부산', '서울', '서울', '부산', '경기', '경기', '경기'],
'요일': ['월요일', '화요일', '수요일', '월요일', '화요일', '월요일', '목요일', '금요일', '화요일', '수요일', '목요일', '금요일'],
'강수량': [100, 80, 1000, 200, 200, 100, 50, 100, 200, 100, 50, 100],
'강수확률': [80, 70, 90, 10, 20, 30, 50, 90, 20, 80, 50, 10]
})
df
Out[24]:
pivot¶
- dataframe의 형태를 변경
- 인덱스, 컬럼, 데이터로 사용할 컬럼을 명시
In [25]:
df.pivot(index = '지역', columns = '요일') # value를 따로 지정하지 않으면 자동 지정
Out[25]:
In [26]:
df.pivot(index = '요일', columns = '지역')
Out[26]:
In [29]:
df.pivot(index = '요일', columns = '지역', values = '강수량')
Out[29]:
pivot_table¶
- 기능적으로 pivot과 동일
- pivot과의 차이점
- 중복되는 모호한 값이 있을 경우, aggregation 함수 사용하여 값을 채움
In [30]:
## 중복된 데이터 적용한 df
df = pd.DataFrame({
'지역': ['서울', '서울', '서울', '경기', '경기', '부산', '서울', '서울', '부산', '경기', '경기', '경기'],
'요일': ['월요일', '월요일', '수요일', '월요일', '화요일', '월요일', '목요일', '금요일', '화요일', '수요일', '목요일', '금요일'],
'강수량': [100, 80, 1000, 200, 200, 100, 50, 100, 200, 100, 50, 100],
'강수확률': [80, 70, 90, 10, 20, 30, 50, 90, 20, 80, 50, 10]
})
df
Out[30]:
In [31]:
## 중복 허용 후 호출 --> ERROR
df.pivot(index = '지역', columns = '요일')
In [32]:
## 중복된 값은 aggfunc으로 처리
pd.pivot_table(df, index = '지역', columns = '요일', aggfunc = np.mean)
Out[32]:
4. stack, unstack함수의 이해 및 활용하기¶
stack & unstack¶
- stack : 컬럼 레벨에서 인덱스 레벨로 dataframe 변경
- 즉, 데이터를 쌓아올리는 개념으로 이해하면 쉬움
-
unstack : 인덱스 레벨에서 컬럼 레벨로 dataframe 변경
- stack의 반대 operation
-
둘은 역의 관계에 있음
In [35]:
df = pd.DataFrame({
'지역': ['서울', '서울', '서울', '경기', '경기', '부산', '서울', '서울', '부산', '경기', '경기', '경기'],
'요일': ['월요일', '화요일', '수요일', '월요일', '화요일', '월요일', '목요일', '금요일', '화요일', '수요일', '목요일', '금요일'],
'강수량': [100, 80, 1000, 200, 200, 100, 50, 100, 200, 100, 50, 100],
'강수확률': [80, 70, 90, 10, 20, 30, 50, 90, 20, 80, 50, 10]
})
df
Out[35]:
In [37]:
# 멀티 인덱스 생성
new_df = df.set_index(['지역', '요일'])
new_df
Out[37]:
In [38]:
new_df.unstack(0) # 0번째 인덱스 (지역 인덱스)를 column 레벨로 올려라
Out[38]:
In [39]:
new_df.unstack(1) # 0번째 인덱스 (요일 인덱스)를 column 레벨로 올려라
Out[39]:
In [40]:
new_df.unstack(0).stack(0) # 0번째 컬럼(안쪽부터)을 인덱스 레벨로 올려라
Out[40]:
In [41]:
new_df.unstack(0).stack(1) # 1번째 컬럼(안쪽부터)을 인덱스 레벨로 올려라
Out[41]:
5. concat 함수로 데이터 프레임 병합하기¶
concat 함수 사용하여 dataframe 병합하기¶
- pandas.concat 함수
- 축을 따라 dataframe을 병합 가능
- 기본 axis = 0 -> 행단위 병합
- axis = 1 -> 열단위 병합
- column 명이 같은 경우
In [43]:
df1 = pd.DataFrame({'key1' : np.arange(10), 'value1' : np.random.randn(10)})
In [42]:
df2 = pd.DataFrame({'key1' : np.arange(10), 'value1' : np.random.randn(10)})
In [44]:
pd.concat([df1, df2]) # default : axis = 0 : 행 기준
Out[44]:
In [45]:
pd.concat([df1, df2], axis = 1) # 열 레벨 기준
Out[45]:
- column 명이 다른경우
In [46]:
df3 = pd.DataFrame({'key2' : np.arange(10), 'value2' : np.random.randn(10)})
In [47]:
pd.concat([df1, df3]) # 컬럼이 맞지 않으면 추가 데이터 생성하고, na를 생성
Out[47]:
Merge & join 함수로 데이터 프레임 병합하기¶
dataframe merge¶
-
SQL의 join처럼 특정한 column을 기준으로 병합
- join 방식: how 파라미터를 통해 명시
- inner: 기본값, 일치하는 값이 있는 경우
- left: left outer join
- right: right outer join
- outer: full outer join
- join 방식: how 파라미터를 통해 명시
-
pandas.merge 함수가 사용됨
In [48]:
customer = pd.DataFrame({'customer_id' : np.arange(6),
'name' : ['철수'"", '영희', '길동', '영수', '수민', '동건'],
'나이' : [40, 20, 21, 30, 31, 18]})
customer
Out[48]:
In [49]:
orders = pd.DataFrame({'customer_id' : [1, 1, 2, 2, 2, 3, 3, 1, 4, 9],
'item' : ['치약', '칫솔', '이어폰', '헤드셋', '수건', '생수', '수건', '치약', '생수', '케이스'],
'quantity' : [1, 2, 1, 1, 3, 2, 2, 3, 2, 1]})
orders.head()
Out[49]:
- on
- join 대상이 되는 column 명시
In [50]:
pd.merge(customer, orders,
on = 'customer_id', # 무엇을 기준으로 merge할 것인지
how = 'inner' # 어떻게 조인할 것인지 (inner, left, outer, right)
)
Out[50]:
In [51]:
pd.merge(customer, orders,
on = 'customer_id', # 무엇을 기준으로 merge할 것인지
how = 'left' # 왼쪽을 기준으로 merge. 값이 없으면 NA
)b
Out[51]:
- index 기준으로 join하기
In [52]:
cust1 = customer.set_index('customer_id')
order1 = orders.set_index('customer_id')
In [53]:
cust1
Out[53]:
In [54]:
order1
Out[54]:
In [55]:
pd.merge(cust1, order1, left_index = True, right_index = True)
Out[55]:
연습문제¶
- 가장 많이 팔린 아이템은?
- 영희가 가장 많이 구매한 아이템은?
In [61]:
# 1. 가장 많이 팔린 아이템은? -> 수건
pd.merge(customer, orders, on = 'customer_id').groupby('item').sum().sort_values(by = 'quantity', ascending = False)
Out[61]:
In [65]:
# 2. 영희가 가장 많이 구매한 아이템은? -> 치약
pd.merge(customer, orders, on = 'customer_id').groupby(['name', 'item']).sum().loc['영희', 'quantity']
Out[65]:
join 함수¶
- 내부적으로 pandas.merge 함수 사용
- 기본적으로 index를 사용하여 left join
In [68]:
cust1.join(order1, how = 'inner') ## merge와 동일
Out[68]:
반응형
'Study > ML_Basic' 카테고리의 다른 글
머신러닝과 데이터 분석 A-Z 올인원 패키지 - 회귀분석_수학적 개념 이해(2) - 통계적 추론과 검정통계 (0) | 2020.12.08 |
---|---|
머신러닝과 데이터 분석 A-Z 올인원 패키지 - 회귀분석_수학적 개념 이해(1) - 확률과 통계 (0) | 2020.12.03 |
머신러닝과 데이터 분석 A-Z 올인원 패키지 - 데이터 분석을 위한 Python(Pandas) – (2) (0) | 2020.09.30 |
머신러닝과 데이터 분석 A-Z 올인원 패키지 - 데이터 분석을 위한 Python(Pandas) – (1) (0) | 2020.09.30 |
머신러닝과 데이터 분석 A-Z 올인원 패키지 - 데이터 처리를 위한 Python(Numpy)(2) (0) | 2020.09.30 |