티스토리 뷰

반응형

그룹 연산(Group by)

 

 - 연산대상.groupby(그룹핑 대상)

 - groupby의 결과는 Dictionary 형태

 - groupby 수행 시 결과는 보여주지 않음

    <pandas.core.groupby.groupby.DataFrameGroupBy object at 0x000001E8F2CBA9E8>로 그룹핑이 되었다고만 출력

 - 분리 -> 적용 -> 결합

   : 다른 언어와 다르게 파이썬은 분리(split)까지 동작. 적용과 결합을 위해 연산 메서드를 적용

 

pd.groupby?

pd.groupby(*args, **kwargs)

 

 

 

 

 

#. 그룹 연산(pd.groupby)

sub = pd.read_csv('subway.csv', encoding='cp949')

 

 

노선번호별 승차에 대한 평균

# 방법 1)  일부 컬럼 전달(속도상 유리)

 

sub['승차'].groupby(sub['노선번호']).mean()   

 

 

# 방법 2) 전체(연산 가능한 모든 컬럼전달 후 색인

 

sub.groupby(sub['노선번호']).mean()   

 

 

sub.groupby(sub['노선번호']).mean()['승차']

 

sub.groupby(sub['노선번호'])['승차'].mean()

 

 

 

 

#. 여러 함수 적용 (.agg)

sub.iloc[:,[0,2,3]].groupby('노선번호').agg(['sum','mean'])

 

 

 

#. 요약 (.describe)

data = sub.iloc[:,[0,2,3]].groupby('노선번호').agg(['sum','mean'])

 

data.describe()      # 문자열은 제외 후 요약

 

 

 

#. 지정 그룹으로 행or열 묶기

sub = pd.read_csv('subway.csv', encoding='cp949')

 

sub['노선번호'] = sub['노선번호'].map(lambda x : int(x.split('_')[1]))   # 노선번호 정제

sub = sub.set_index('노선번호').iloc[:,1:].T    # 정제된 노선번호를 index로 지정, 시간 컬럼을 제외 후 행/열 전치

 

ar1 = np.where(sub.columns <= 4, 'one', 'two')   # 지정 그룹으로 묶기

sub.groupby(ar1, axis=1).sum()

 

 

 

 

 

#. 그룹별 데이터 수 확인 (.count, .size)

 

sub.groupby(sub['노선번호'])['승차'].count() 

 

sub.groupby(sub['노선번호'])['승차'].size()

 

 

 

 

#. group_key(index) 생략

data3.groupby('역').apply(top,'승차')

 

* Duplicated level name: " ", assigned to level 1, is already used for level 0 오류 발생 시 필요

data3.groupby('역', group_keys=False).apply(top,'승차')

 

 

 

 

#. Q1

 

import pandas as pd

import numpy as np

from pandas import Series, DataFrame

import matplotlib.pyplot as plt

 

%matplotlib qt

 

 

# subway2.csv 파일을 읽고

 

sub2 = pd.read_csv('subway2.csv', encoding='cp949', skiprows=True)

 

sub2 = sub2.fillna(method='ffill')      # NA값을 앞 행의 값으로 채우기

 

 

 

# 1) 각 시간대 별 승차와 하차의 평균과 합

 

sub2.groupby('구분').mean()   # 시간대별 승하차의 평균

 

 

sub2.groupby('구분').sum()   # 시간대별 승하차의 합

 

 

 

sub2.groupby('구분').agg(['sum','mean'])  # 시간대별 승하차의 평균과 합

                                                         # agg : 여러 그룹 연산을 수행 시, 함수를 결합해서 출력

 

 

 

# 2) 각 역별 전체 승차와 하차의 평균과 합

 

sub2.set_index(['전체','구분']).mean(1).unstack()    

= sub2.groupby(['전체','구분']).mean().mean(1).unstack()   # mean()이 두 번 사용된 이유는, groupby의 결과가 dictionary 형태이므로, 그룹별 mean()(여기서는 변화가 없겠지만)을 통해 DataFrame 형태로 변환시킨 후, mean(1)을 적용시키기 위함

 

 

 

sub2.set_index(['전체','구분']).sum(1).unstack()

= sub2.groupby(['전체','구분']).sum().sum(1).unstack()    # 마찬가지로 sum()이 두 번 사용된 이유는, groupby의 결과가 dictionary 형태이므로, 그룹별 sum()(여기서는 변화가 없겠지만)을 통해 DataFrame 형태로 변환시킨 후, sum(1)을 적용시키기 위함

 

 

 

 

# 3) 각 시간대 별 승차수가 가장 높은 역

 

data1 = sub2.set_index(['전체','구분'])

 

data1.xs('승차', level=1).idxmax()

 

 

 

 

# 4) 승차가 가장 많은 top 10개의 역을 구하고 각 역의 시간대별 승차의 증감추세를 도표화 

 

data2 = data1.xs('승차', level=1)

 

 

ind = data1.xs('승차', level=1).sum(1).sort_values(ascending=False)[:10].index

Index(['강 남', '잠 실', '신 림', '삼 성', '강 변', '고속터미', '선 릉', '서울역(1)', '구로공단', '신 촌'],

 

      dtype='object', name='전체')

 

 

data3 = data2.loc[ind]

 

data3.columns = data3.columns.str[:2].astype('int')

 

 

data3.columns.names = ['시간']

 

data3.T.plot()

 

plt.xticks(data3.columns)

 

 

 

 

# 5) 지역별 승차의 합

 

data3.groupby(['강남','강남','강남','강남','강남','강남','강남','강북','강남','강북',]).sum()

 

 

 

 

# 6) 오전/오후 승차의 합

 

ar1 = np.where(data3.columns <= 12,'오전','오후')

 

data3.groupby(ar1,axis=1).sum()

 

 

 

 

#. Q2 (사용자 정의 함수 전달)

sub = pd.read_csv('subway2.csv', encoding='cp949', skiprows=True)

sub = sub.fillna(method='ffill')

 

data1 = sub.set_index(['전체','구분'])     # 멀티 인덱스

data2 = data1.xs('승차',level=1)         # 승차 인덱스 추출

 

data3 = data2.stack().reset_index()    # .reset_index : index를 columns으로 

                                                   # groupby(, as_index=False) : 인덱스를 컬럼으로

 

data3.columns = ['역','시간','승차']

data3.groupby('역', group_keys=False).apply(top,'승차')  # group_keys : key 생략 

 

# 역별 승하차 합계

data1.groupby(level=0).sum()  # groupby에 level 전달 가능

 

# 전체 역의 승하차 합계

data1.groupby(level=1).sum()  # 전체 역의 승하차 합계

 

# 사용자 정의 함수의 전달 예

f1 = lambda x : x.max() - x.min()

sub.groupby('전체')['05~06'].apply(f1)  

 

# top(df,col,n) 함수 생성 및 적용

top = lambda data, col, n=5 : data.sort_values(by=col,ascending=False)[:n]

 

df1 = DataFrame(data2.stack(), columns=['승차'])      # 컬럼 전달을 위해 dataframe으로 변환

df1.groupby(level=0, group_keys=False).apply(top,'승차')

    * 

Duplicated level name: " ", assigned to level 1, is already used for level 0 오류 발생 원인,

       groupby 키가 원본에 포함 시, 키 값이 중복되면 키 충돌로 에러 발생 => group_keys=False 옵션으로 해결

 

 

 

#. Q3

# kimchi_test파일을 불러온 후

kimchi = pd.read_csv('kimchi_test.csv', encoding='cp949')

 

 

# 1) 각 년도별 제품별 판매량과 판매금액의 평균

kimchi.groupby(['판매년도','제품'])['수량','판매금액'].mean().unstack()    # unstack 하위 인덱스가 컬럼화

                                                                                                 # stack 컬럼의 인덱스화

 

# 2) 각 년도별 제품별 판매처별 판매량과 판매금액 평균

kimchi.groupby(['판매년도','제품','판매처'])['판매금액','수량'].mean().unstack()

 

 

# 3) 각 제품별 판매수량이 0~ 10000, 10000~20000, 20000~ 의 판매량을 기록한 월이 몇 회인지 확인

l1 = [0,10000,20000,100000]

c1 = pd.cut(kimchi['수량'], l1, right=False)

 

c1.groupby([kimchi['제품'],c1]).count().unstack()

 

# 4) 각 김치별로 가장 많이 팔리는 월과 해당 월의 판매량을 김치이름과 함께 출력

kimchi.groupby(['제품','판매월'])['수량'].sum().unstack(level=0)

 

kimchi.groupby(['제품','판매월'])['수량'].sum().unstack(level=0).idxmax()

 

 

# 5) 각 월별로 김치의 판매량을 비교할 수 있도록 막대그래프로 표현

data = kimchi.groupby(['제품','판매월'])['수량'].sum().unstack(level=0)

plt.rc('font', family='MalGun Gothic')

data.plot(kind='bar')

plt.ylim([0,300000])

plt.xticks(rotation=0)

 

 

 

#. Q3

# 병원현황.csv 데이터를 불러온 후

hosp = pd.read_csv('병원현황.csv',engine='python', skiprows=1)

 

data1 = hosp.drop(['항목','단위'], axis=1).set_index(['시군구명칭','표시과목'])  # 멀티 컬럼 설정

 

col1 = data1.columns.str.split('. ').str.get(0)   # 컬럼명 분리

col2 = data1.columns.str.split('. ').str.get(1)

 

data1.columns=[col1,col2]  # 컬럼명 설정

 

 

# 1) 각 년도별 구별 병원의 수 출력

# 1. 데이터의 '계' 인덱스 활용

data_total = data1.xs('계', level=1)   

data_total.groupby(axis=1, level=0).sum()

 

 

# 2. 데이터의 '계' 인덱스 미활용

data_rm = data1.drop('계', level=1)    

data_rm.groupby(axis = 1, level=0).sum()   # 컬럼의 같은 연도끼리 그룹

 

data_rm.groupby(axis = 1, level=0).sum().groupby(axis=0,level=0).sum()    컬럼의 같은 연도끼리 그룹 후 인덱스의 같은 구끼리 그룹

 

# 2) 성형외과의 년도별 증가 추이

data1.xs('성형외과', level=1).groupby(level=0, axis=1).sum()  # 인덱스가 성형외과에 해당하는 데이터만 추출 후, 같은 연도끼리 그룹

plot1 = data1.xs('성형외과', level=1).groupby(level=0, axis=1).sum().sum()

   

1.                                                             2.

 

plot1.index = plot1.index.astype('int')

plot1.plot()

plt.xticks(plot1.index)

 

 

# 3) 강남구 년도별 증가 추이

plot2 = data_rm.xs('강남구').groupby(level=0, axis=1).sum().sum()

 

plot2.index = plot2.index.astype('int')

plot2.plot()

plt.xticks(plot2.index)

 

# 4) 2013년 기준, 각 병원의 구별 점유율을 출력

data2 = data_rm.xs('2013',axis=1).sum(1).unstack()

 

f1 = lambda x : round(x / x.sum() * 100, 2)

data2.apply(f1).dropna(axis=1)

 

 

data2.apply(f1).sum()   # 결과 확인 (반올림으로 발생한 약간의 오차)

 

 

data2.apply(f1)['성형외과'].sort_values(ascending=False)  # 특정 병원의 점유율이 많은 구 확인

 

# 5) 년도별 각 병원의 총 건수를 병원별로 비교할수 있도록 막대그래프 표현

plot3 = data_rm.groupby(level=0, axis=1).sum().groupby(level=1, axis=0).sum().T

 

plt.rc('font', family='MalGun Gothic')

plot3.plot(kind='bar', ylim=(0,7000))

plt.xticks(rotation=0)

plt.legend(fontsize='small')

 

subway.csv
0.00MB

 

 

 

고: KIC 캠퍼스 머신러닝기반의 빅데이터분석 양성과정

 

반응형
댓글
최근에 올라온 글
최근에 달린 댓글
링크
Total
Today
Yesterday