import numpy as np
import pandas as pd
# 데이터 프레임 생성
np.random.seed(1)
df = pd.DataFrame({
'key1': ['a', 'a', 'b', 'b', 'a'],
'key2': ['one', 'two', 'one', 'two', 'one'],
'data1': np.random.randint(0, 10, 5),
'data2': np.random.randint(0, 10, 5)
})
print(df)
  key1 key2  data1  data2
0    a  one      5      0
1    a  two      8      1
2    b  one      9      7
3    b  two      5      6
4    a  one      0      9
grouped1 = df.groupby(by='key1')
print(grouped1) # DataFrameGroupBy 객체 - 그룹 연산을 적용하기 위해 만든 객체
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x00000172F6BAAA88>
# DataFrameGroupBy 객체 - 그룹 연산을 적용하기 위해 만든 객체
# 그룹 연산: count, sum, mean, median, var, std, min, max, ...
cnt = grouped1['data1'].count()
print(type(cnt))
print(cnt)
print(cnt['a'], cnt['b'])
<class 'pandas.core.series.Series'>
key1
a    3
b    2
Name: data1, dtype: int64
3, 2
print(grouped1['data1'].mean())  # 숫자 데이터 컬럼들에만 mean()함수를 적용해줌
print(grouped1.mean()) 
print(grouped1[['data1', 'data2']].mean())
key1
a    4.333333
b    7.000000
         data1     data2
key1                    
a     4.333333  3.333333
b     7.000000  6.500000
         data1     data2
key1                    
a     4.333333  3.333333
b     7.000000  6.500000
grouped2 = df.groupby(by='key2')
print(grouped2.mean())
         data1     data2
key2                    
one   4.666667  5.333333
two   6.500000  3.500000
# groupby의 기준(by)이 2개 이상의 컬럼일 때는 리스트를 전달
grouped3 = df.groupby(by=['key1', 'key2'])
print(grouped3.mean())
print(grouped3['data1'].count())
           data1  data2
key1 key2              
a    one     2.5    4.5
     two     8.0    1.0
b    one     9.0    7.0
     two     5.0    6.0
key1  key2
a     one     2
      two     1
b     one     1
      two     1
Name: data1, dtype: int64
people = pd.DataFrame(np.random.randint(0, 10, (5, 5)),
          columns=['a', 'b', 'c', 'd', 'e'],
          index=['Joe', 'Steve', 'Wes', 'Jim', 'Travis'])
print(people)
        a  b  c  d  e
Joe     2  4  5  2  4
Steve   2  4  7  7  9
Wes     1  7  0  6  9
Jim     9  7  6  9  1
Travis  0  1  8  8  3
print(people.groupby(len).sum())
print(people.groupby(lambda x: x.startswith('J')).sum())
    a   b   c   d   e
3  12  18  11  17  14
5   2   4   7   7   9
6   0   1   8   8   3
        a   b   c   d   e
False   3  12  15  21  21
True   11  11  11  11   5
if __name__ == '__main__':
     # with-as 구문을 사용해서 오라클 DB 서버에 접속
     dsn = cx_Oracle.makedsn('localhost', 1521, 'orcl')
     with cx_Oracle.connect('scott', 'tiger', dsn) as connection:
     # with-as 구문을 사용해서 Cursor 객체를 생성
          with connection.cursor() as cursor:
          # scratch09 패키지에서 작성한 테이블 전체 검색 함수를 사용해서,
               # emp_df 데이터 프레임을 생성
               emp_df = select_all_from('emp', cursor)
               # emp_df를 csv 파일로 저장
               emp_df.to_csv('emp_df.csv', index=False)
               # emp_df에서 부서별 평균 급여를 출력
               grouped_by_deptno = emp_df.groupby('DEPTNO')
               sal_by_dept = grouped_by_deptno['SAL']
               print(sal_by_dept.mean())
               # emp_df에서 부서별 인원수를 출력
               print(sal_by_dept.count())
               # emp_df에서 부서별 급여 최솟값 출력
               print(sal_by_dept.min())
               # emp_df에서 부서별 급여 최댓값 출력
               print(sal_by_dept.max())
DEPTNO
10    2916.666667
20    2175.000000
30    1566.666667
Name: SAL, dtype: float64
DEPTNO
10    3
20    5
30    6
Name: SAL, dtype: int64
DEPTNO
10    1300.0
20     800.0
30     950.0
Name: SAL, dtype: float64
DEPTNO
10    5000.0
20    3000.0
30    2850.0
Name: SAL, dtype: float64
# 위의 결과를 하나의 데이터 프레임으로 출력
df = pd.DataFrame({
     'count': sal_by_dept.count(),
     'mean': sal_by_dept.mean(),
     'min': sal_by_dept.min(),
     'max': sal_by_dept.max()
     })
print(df)
print(df.shape)
        count         mean     min     max
DEPTNO                                    
10          3  2916.666667  1300.0  5000.0
20          5  2175.000000   800.0  3000.0
30          6  1566.666667   950.0  2850.0
(3, 4)
# agg(), aggregate(): 파라미터에 함수 이름(또는 리스트)을 전달하면,
# GroupBy 객체에 함수를 적용함.
# sal_by_dept.mean() 와
# sal_by_dept.agg('mean')는 동일한 동작
# 함수가 집계 함수(pandas.Series 또는 pandas.DataFrame 클래스가
# 가지고 있는 메소드들: count, mean, sum, ...)인 경우에는 함수 이름을
# 문자열로 전달함.
# 개발자가 작성한 함수는 함수 이름을 파라미터에 전달해야 함.
df = sal_by_dept.agg(['count', 'mean', 'min', 'max', peak_to_peak])
print(df)
        count         mean     min     max  peak_to_peak
DEPTNO                                                  
10          3  2916.666667  1300.0  5000.0        3700.0
20          5  2175.000000   800.0  3000.0        2200.0
30          6  1566.666667   950.0  2850.0        1900.0
# print(sal_by_dept.agg(pd.Series.mean)) 코드를 쉽게 사용할 수 있도록
# print(sal_by_dept.agg('mean')) 코드와 같은 호출 방식도 제공.
# emp_df에서 직책별 직원 수, 급여 평균, 최소, 최댓값을 출력
grouped_by_job = emp_df.groupby('JOB')
sal_by_job = grouped_by_job['SAL']
print(sal_by_job.agg(['count', 'mean', 'min', 'max',
                     lambda x: x.max() - x.min()]))
           count         mean     min     max  <lambda_0>
JOB                                                      
ANALYST        2  3000.000000  3000.0  3000.0         0.0
CLERK          4  1037.500000   800.0  1300.0       500.0
MANAGER        3  2758.333333  2450.0  2975.0       525.0
PRESIDENT      1  5000.000000  5000.0  5000.0         0.0
SALESMAN       4  1400.000000  1250.0  1600.0       350.0
# agg() 함수가 만드는 DataFrame의 컬럼 이름을 설정할 때는
# keyword-argument 방식 또는 dict를 파라미터로 전달함.
print(sal_by_job.agg(Count='count',
                     Average='mean',
                     Minimum='min',
                     Maximum='max',
                     Range=lambda x: x.max() - x.min()))
           Count      Average  Minimum  Maximum  Range
JOB                                                   
ANALYST        2  3000.000000   3000.0   3000.0    0.0
CLERK          4  1037.500000    800.0   1300.0  500.0
MANAGER        3  2758.333333   2450.0   2975.0  525.0
PRESIDENT      1  5000.000000   5000.0   5000.0    0.0
SALESMAN       4  1400.000000   1250.0   1600.0  350.0
# emp_df에서 부서별, 직책(job)별 직원 수, 급여 평균, 최소, 최댓값 출력
grouped = emp_df.groupby(['DEPTNO', 'JOB'])
sal_by_dept_job = grouped['SAL']
df = sal_by_dept_job.agg({
     'count': 'count',
     'minimum': 'min',
     'maximum': 'max',
     'average': 'mean',
     'range': lambda x: x.max() - x.min()
})
# agg(), aggregate() 함수의 파라미터에 dict를 전달하는 방식은
# pandas 패키지가 업그레이드될 때 없어질 수 있는 기능(deprecated).
# dict 방식보다는 keyword-argument 방식을 사용하는 것이 안전함.
print(df)
                  count  minimum  maximum  average  range
DEPTNO JOB                                               
10     CLERK          1   1300.0   1300.0   1300.0    0.0
       MANAGER        1   2450.0   2450.0   2450.0    0.0
       PRESIDENT      1   5000.0   5000.0   5000.0    0.0
20     ANALYST        2   3000.0   3000.0   3000.0    0.0
       CLERK          2    800.0   1100.0    950.0  300.0
       MANAGER        1   2975.0   2975.0   2975.0    0.0
30     CLERK          1    950.0    950.0    950.0    0.0
       MANAGER        1   2850.0   2850.0   2850.0    0.0
       SALESMAN       4   1250.0   1600.0   1400.0  350.0
'Python > Python기초' 카테고리의 다른 글
| Python 61_ pandas dataframe, numpy array, apply함수 (0) | 2020.02.13 | 
|---|---|
| Python 60_ pandas _ aggregate2 (0) | 2020.02.12 | 
| Python 58_ pandas4_ Database (0) | 2020.02.10 | 
| Python 57_Pandas 3_ Data Type, DataFrame만들기, 인덱싱, 정렬 (0) | 2020.02.07 | 
| Python 56_ pandas와 dataframe (0) | 2020.02.06 |