본문 바로가기
Python/데이터 분석

[DataFrame] DataFrame - Grouping, pivot_table

by snow_white 2022. 4. 8.

groupby()

  • 데이타를 특정 기준으로 그룹핑 할때 사용(엑셀의 피봇 테이블과 유사)그룹핑을 한 후에는 반드시 통계함수를 적용한다.

그룹핑 => 세분화시킨다세분화 된 객체들의 통계함수를 적용하여 구한다

# 성별로 그룹핑
# 성별로 그룹핑하면 데이터프레임이 두동강 나잖아!
# groupby 함수만으로는 아무것도 출력되지 않는다.
# 그룹핑 된 객체 자체만 반환된다. DataFrameGroupBy
tips.groupby('sex') # <pandas.core.groupby.generic.DataFrameGroupBy object at 0x000002162A57B6D0>

# 출력 결과를 받아 보려면.. DataFrameGroupBy 객체에 통계함수를 적용
tips.groupby('sex').describe()

# 평균 함수를 적용해보면 numeric한 칼럼만 추출됨
tips.groupby('sex').mean()

# 흡연, 비흡연자 여부로 그룹핑... 평균가를 출력
tips.groupby('smoker').mean()

그룹핑 한 다음에 칼럼에 대한 평균값과 총합, count를 알고 싶다

통계함수를 복수 개로 적용해보자 => agg() 사용하자

 

복수의 통계

  • agg() => agregatedf.groupby('그룹핑 할 칼럼명').agg(['sum', 'mean', 'count'])
# 그룹핑할 때 어떤 칼럼으로 하는지에 따라 해당 칼럼이 인덱스로 적용된다
# size 칼럼으로 그룹핑하여 인덱스가 size(인원수)로 지정됨
# groupby하여 인덱스, columns, values가 나온 걸 보아하니 데이터프레임이구나
tips.groupby('size').agg(['sum', 'mean', 'count']) # <pandas.core.groupby.generic.DataFrameGroupBy object at 0x000002162D89ED90>

여러 개 컬럼으로 그룹핑

# 흡연으로 그룹핑, 성별로 또 한 번 그룹핑, 통계함수 mean()
tips.groupby(['smoker', 'sex']).mean()

tips.groupby(['smoker', 'day']).agg(['mean','sum'])

tips.pivot_table(index=['sex','day'], aggfunc=['mean','sum'])

✅ 요일별 팁의 평균

# Series로 반환됨
tips.groupby('day')['tip'].mean() 
# 시리즈로 반환됨 (데이터프레임에서 칼럼만 쏙 빼낸 거니까!)

# 데이터프레임으로 나타내기 위해서는 [ ] 꺽쇠 추가해주자
tips.groupby('day')[['tip']].mean()

# 요일별 평균 팁
tips.groupby('day')[['tip']].agg('mean')

# pivot_table에서는 agg가 안 먹힘!!

# pivot 테이블로 구성
tips.pivot_table(index='day', aggfunc='mean')[['tip']]

 

 


 

2. 피봇테이블

 

pivot_table() 피봇함수는 DataFrame의 데이타를 Reshaping 하는 방법중 하나이다.

 

pivot_table 속성값, 위치매개변수로 아래 세 가지 속성이 들어있음 순서 중요

  • values : 채우고자 하는 값
  • index : 그룹핑 기준
  • columns : 컬럼값
tips.pivot_table?
'''
agg 안 하면 default가 mean() 평균을 구해준다
Signature:
tips.pivot_table(
    values=None,
    index=None,
    columns=None,
    aggfunc='mean',
    fill_value=None,
    margins=False,
    dropna=True,
    margins_name='All',
    observed=False,
    sort=True,
) -> 'DataFrame'
'''

# 성별을 나누어 분류하고 요일별로 나누어 분류하기
tips.pivot_table(index=['sex','day']).round(2)

 

 

 

 

 

 

tips.pivot_table(values=['total_bill','tip'],
                index=['sex','day'], 
                 columns='smoker'
                )

 

 

 

 

 

data = {
    "도시": ["서울", "서울", "서울", "부산", "부산", "부산", "인천", "인천"],
    "연도": ["2015", "2010", "2005", "2015", "2010", "2005", "2015", "2010"],
    "인구": [99,      96,     90,      34,   33,     28,     28    , 23],
    "지역": ["수도권", "수도권", "수도권", "경상권", "경상권", "경상권", "수도권", "수도권"]
}

df1 = DataFrame(data)
df1

# 딕셔너리의 키가 데이터프레임의 칼럼이 된다

 

# index는 어떤 걸로 그룹핑하고 싶은지
df1.pivot_table(index='도시', columns='연도', values='인구')
df1.pivot_table('인구','도시','연도')
df1.pivot_table('인구',index='도시', columns='연도')

# 위치 매개변수가 뒤에 가면 안 됨!!!!!!!!!
#df1.pivot_table(index='도시', columns='연도', '인구')
#df1.groupby()

 

# 연도별, 도시별 인구 감소 추이
df1.pivot_table(index=['연도','도시'], values='인구')

# 순서 바꿔서 도시별, 연도별 인구 추이
df1.pivot_table(index=['도시','연도'], values='인구')

 

 

 

# grouoby로 표현
df1.groupby(['연도','도시'])[['인구']].mean()

 

 

 

 

 

파일 저장

csv 파일로 저장

df1.to_csv('cities.csv', encoding='euc-kr')

엑셀 파일로 저장

# index=False 불필요한 인덱스 삭제
df1.to_excel('cities.xlsx', index=False, sheet_name='myCity')

상관관계

컬럼별 상관관계를 확인할 수 있다.

1에 가까울수록 연관성이 높고

-1에 가까울수록 반비례 관계

tips.corr()

여성, 남성 | 흡연자, 비흡연자궁극적으로 각 그룹에서 가장 많은 팁과 가장 작은 팁의 차이를 알고싶다. 그 중에서 성별, 흡연여부 관련 그룹 중 어디서 가장 많은 팁의 차이가 나는지 알아보도록 하자.

사용자 정의 함수를 만들어서 apply 적용하고,tip 결과가 높은 것부터 출력 되도록 정렬해 보세요.

def max_min_tip(x):
    return x.max() - x.min()

result = tips.groupby(['sex','smoker'])[['tip']].apply(max_min_tip)
result.sort_values(by='tip', ascending=False)

댓글