DataFrameGroupBy.filter(func, dropna=True, *args, **kwargs)
집계결과가 아니라 값들을 다 출력
# cnt1 - 사과: 10대, 귤: 20대, 배: 단단위, 딸기 30이상
data = dict(fruits=['사과', '사과','사과', '사과','사과','귤','귤','귤','귤','귤','배','배','배','배','배','딸기','딸기','딸기','딸기','딸기']
,cnt1=[10, 12, 13, 11, 12, 21, 22, 27, 24, 26, 7, 7, 8, 3, 2, 30, 35, 37, 41, 28]
,cnt2=[100, 103, 107, 107, 101, 51, 57, 58, 57, 51, 9, 9, 5, 7, 7, 208, 217, 213, 206, 204]
)
df = pd.DataFrame(data)
df
df['fruits'].unique()
# 1
r = df.groupby('fruits')['cnt1'].mean()
r
# 2
r>=20
# 3
r[r>=20]
# 단순히 집계 결과가 아니라 데이터를 다 보고싶다.
# 귤과 딸기의 전체 데이터를 다 보겠다
# 그룹의 원소 데이터를 다 보겠다
# 그 때 필터를 쓴다.
def check_mean1(x):
'''
[매개변수]
x : DataFrame - groupby에 의해 그룹핑된 DataFrame들 하나하나를 받는다.
[반환값]
boolean : cnt1의 평균이 20 이상인지 여부를 반환.
'''
return x['cnt1'].mean() >= 20
# 필터 사용하기
df.groupby('fruits').filter(check_mean1)
# 이 조건을 만족하는 데이터를 보고싶은 것.
# 데이터 전체를 다 보고싶은 것.
# dropna
df.groupby('fruits').filter(check_mean1, dropna=False)
# NA로 반환해준다.
DataFrameGroupBy.transform(func, *args)
SeriesGroupBy..transform(func, *args)
# 각각의 원소값과 통계량을 같이 볼 때
# 결측치 채울 때
# 트랜스폼 사용하기
df.groupby('fruits').transform(lambda x:10)
# 트랜스폼으로 평균
df.groupby('fruits').transform('mean')
# 그룹 별로 평균을 내서 묶어서 주는게 아니라, 각자 준다.
# 형태를 유지하면서 각각의 항목에 채워준다.
df.insert(삽입할 index : int, 컬럼 이름 : str, 삽입할 Series)
# 원본을 유지하기 위해 카피하기
df2 = df.copy()
df2.head()
# 사이에 넣어주기
# insert 중간 열에 끼워넣을 때 사용.
# 시리즈를 데이터 프레임의 중간 컬럼으로 삽입할 때 사용.
r = df.groupby('fruits').transform('mean')
r
# 인서트를 이용해 삽입해보기
df2.insert(2, '과일별 cnt1 평균', r['cnt1'])
# 반환하지 않는다. 원본이 변한다는 뜻
df2
# 컬럼 추가 생성
df2['과일별 cnt2 평균'] = r['cnt2']
# 이렇게 하면 맨 마지막에 추가된다.
df2.head() # 완성
DataFrame.pivot_table(
values=None,
index=None,
columns=None,
aggfunc='mean',
fill_value=None,
margins=False,
dropna=True,
margins_name='All')
flights = pd.read_csv('data/flights.csv', encoding='UTF-8')
flights.shape
# 에어라인으로 그룹지은 에어타임의 평균
flights.groupby('AIRLINE')['AIR_TIME'].mean()
# 피봇 테이블
flights.pivot_table(values='AIR_TIME', index='AIRLINE', aggfunc='mean')
# 결과가 무적권 테이터 프레임으로 나온다.
# index 그룹핑할 대상을 인덱스에 지정해 준다.
# aggfunc
# 위나 아래나 똑같다. 차이가 있다면 데이터 프레임으로 만들어 준다는 것
# sql의 롤업같이 중간 집계
# flights.pivot_table(values='AIR_TIME', index='AIRLINE', aggfunc='mean', margins=True)
# margins all 전체 평균
# 이름 지정해 줄 수 있음
flights.pivot_table(values='AIR_TIME', index='AIRLINE', aggfunc='mean', margins=True, margins_name='전체평균')
# 그룹핑할 인덱스를 컬럼으로 지정하기
flights.pivot_table(values='AIR_TIME', columns='AIRLINE', aggfunc='mean')
# 굳이 피벗 테이블을 써야되나?
# 하나만 그룹핑해서 쓸 때는 굳이 쓸 필요없다.
# 취소 건 수 구하기
flights.groupby(['AIRLINE', 'ORG_AIR'])['CANCELLED'].sum()
# 두 개로 그룹핑해서 집계할 때. 피벗 테이블
flights.pivot_table(values='CANCELLED', index='AIRLINE', columns='ORG_AIR', aggfunc='sum')
# 이거 구나. 왜 쓰는지 알겠다.
# NaN인 애들은 겹치는 게 없는 친구들
# 결측치에 특정한 값 넣어주기
flights.pivot_table(values='CANCELLED', index='AIRLINE', columns='ORG_AIR', aggfunc='sum', fill_value=-1)
# 중간 계 마진스
flights.pivot_table(values='CANCELLED', index='AIRLINE', columns='ORG_AIR', aggfunc='sum', margins=True)
#
flights.groupby(['AIRLINE','MONTH','ORG_AIR'])['ARR_DELAY'].agg(['min','max'])
# 피봇 테이블
flights.pivot_table(values='ARR_DELAY', index=['AIRLINE','MONTH'], columns='ORG_AIR', aggfunc=['min','max'])
Series, DataFrame의 데이터 일괄 처리
DataFrame.apply(함수, axis=0, args=())
Series.apply(함수, args=())
arr = np.arange(24).reshape(6,4)
df = pd.DataFrame(arr, columns=['NO1','NO2','NO3','NO4'])
df
# 함수 생성
def test(x):
print(type(x))
return x*10
# 시리즈에 어플라이 적용하기
df['NO1'].apply(test) # 테스트 함수를 일괄 적용해라! 라는 뜻
# 원본이 바뀌지는 않는다.
# 집계보다는 그냥 일괄적인 처리 느낌
# 마찬가지로 간단한 건 람다로 처리
df['NO1'].apply(lambda x:x*10)
# 데이터 프레임에 어플라이 사용하기
df.apply(test) # 기본적으로 axis=0 한 행씩 넘어간다.
df.apply(np.sum)
df.apply(np.sum, axis=1)
# 요런 것도 가능.
df['NO4'].apply(lambda x:'{}원'.format(x))
cut()/qcut() - 연속형(실수)을 범주형으로 변환
pd.cut(x, bins,right=True, labels=None)
pd.qcut(x, q, labels)
age = pd.Series(np.random.randint(80, size=30))
age
age.value_counts()
# cut으로 나누기
bins = [-1, 9, 21, 40, 80]
age_group = pd.cut(age, bins)
# () : 포함 안함
# [] : 포함한다.
age_group
df = pd.DataFrame({'나이':age, '나이대':age_group})
df
# 라벨 지정해주기
labels = ['유아','청소년','청년','중장년']
age_group = pd.cut(age, bins, labels=labels)
age_group
df = pd.DataFrame({'나이':age, '나이대':age_group})
df
# 응용해보기
df.groupby('나이대')['나이'].agg(['mean','count'])
# qcut
age_group2 = pd.qcut(age, q=5, labels=['유아','청소년','청년','중년','노년'])
age_group2
pd.DataFrame({'나이':age,'나이대':age_group2})
# 컷은 지정해서 자르지만 큐컷은 균등하게 알아서 나눠줌
# 그래서 범위를 알 수가 없다.
age_group2 = pd.qcut(age, q=5, labels=['유아','청소년','청년','중년','노년'], retbins=True)
type(age_group2)
age_group2[0]
age_group2[1]
pd.DataFrame({'나이':age,'나이대':age_group2[0]})