Home python Pandas (11) DataFrame Grouping
Post
Cancel

python Pandas (11) DataFrame Grouping

numpy logo

DataFrame 그룹핑

그룹핑은 pandas`기능과 데이터 분석의 꽃이 아닐까 생각한다.

특정 집단의 집계함수나 유의미한 결과 추론은 어떤 형태의 데이터 분석이든간에 유용하게 쓰이기 때문이다.

pandas 자료구조인 SeriesDataFrame을 갖고 어떻게 그룹핑을 하는지 알아보자.

Series 그룹핑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import numpy as np
import pandas as pd

# 아래와같이 데이터 프레임을 하나 잡아주자!
df = pd.DataFrame({
    '학과': ['컴퓨터', '철학', '컴퓨터', '철학', '컴퓨터'],
    '이름': ['아이유', '김연아', '홍길동', '강감찬', '신사임당'],
    '학년': [1, 2, 3, 2, 3],
    '학점': [1.5, 2.7, 3.5, 1.9, 4.0]
})

display(df)
"""
   학과    이름  학년  학점
0 컴퓨터  아이유   1  1.5
1 철학    김연아  2  2.7
2 컴퓨터  홍길동  3   3.5
3 철학    강감찬  2  1.9
4 컴퓨터  신사임당 3  4.0
"""

# 1 단계 그룹핑
dept = df['학점'].groupby(df['학과'])
display(dept) # <pandas.core.groupby.generic.SeriesGroupBy object at 0x7feb21e27c10>
# dept는 SeriesGroupBy의 객체임.
# 평균값을 알려주는 메서드를 불러오자.
display(dept.mean())
"""
학과
철학     2.3
컴퓨터    3.0
Name: 학점, dtype: float64
"""
# 이렇게 학과별 평균 학점을 알려준다.

# dept는 또한 같은 그룹내 멤버들의 값을 알려주기도 하는데
computer = dept.get_group('컴퓨터') 
# 컴픁에 dept가 갖고 있는 '컴퓨터' 그룹의 특성 (여기선 학점)을 가져와서 computer로 assign 해라!
display(computer)
"""
0    1.5
2    3.5
4    4.0
Name: 학점, dtype: float64
"""

# 또한 그룹 사이즈를 알려주기도 함.
g_size = dept.size()
print(g_size)  # 각 그룹의 사이즈를 알려줌
"""
학과
철학     2
컴퓨터    3
Name: 학점, dtype: float64
"""
# 컴퓨터학과 그룹의 사이즈는 총 3명, 철학과 그룹의 사이즈는 총 2명이란 소리임.

2단계 그룹핑을 할 수도 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
df = pd.DataFrame({
    '학과': ['컴퓨터', '철학', '컴퓨터', '철학', '컴퓨터'],
    '이름': ['아이유', '김연아', '홍길동', '강감찬', '신사임당'],
    '학년': [1, 2, 3, 2, 3],
   '학점': [1.5, 2.7, 3.5, 1.9, 4.0]
})

# 2단계 그룹핑
dept = df['학점'].groupby([df['학과'], df['학년']])
display(dept.mean())
"""
학과    학년
철학     2      2.30
컴퓨터    1      1.50
        3      3.75
Name: 학점, dtype: float64
"""
# 결괏값은 2차 인덱스로 떨어졋음.
# 인덱스가 두개란 소리임.
# pandas Series 임을 기억하자

# 이렇게 처리하면 2차 index를 이용하는 형식이 되기 때문에 사용하기 많이 불편!
# 많이 사용하는 방식은 최하위 인덱스를 column으로 만들어서 DATAFRAME으로 변환
# 이걸 해주는 함수가 하나 있는데 그게 바로 unstack()
display(dept.mean().unstack())  
"""
학년     1    2     3
학과
------------------------
철학   NaN   2.3   NaN
컴퓨터  1.5   NaN   3.75
"""
# 이렇게 하는게 더 깔끔함. 하지만 만능은 아니다. 
# 3, 4 차 넘어가면 dataframe 표현이 안되기에 불가.

Data Frame 그룹핑

일반적으로 Series보다 흔하게 사용할 일이 많다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import numpy as np
import pandas as pd

df = pd.DataFrame({
    '학과': ['컴퓨터', '철학', '컴퓨터', '철학', '컴퓨터'],
    '이름': ['아이유', '김연아', '홍길동', '강감찬', '신사임당'],
    '학년': [1, 2, 3, 2, 3],
    '학점': [1.5, 2.7, 3.5, 1.9, 4.0]
})

# 아까 series때와 정확하게 같은 데이터 사용
# 전에는 칼럼 하나만 떼어와서 pandas series로 왔음.
# 이번엔 데이터프레임 전체에 대해서 groupby 할 것임.
dept = df.groupby(df['학과'])  # groupby 하는건 똑같음
display(dept) # <pandas.core.groupby.generic.DataFrameGroupBy object at 0x7feb21e2e0d0>
# DataFrameGroupBy 로 바뀜.

display(dept.get_group('컴퓨터')) # 컴퓨터 그룹에 대한 정보를 리턴
# 데이터 프레임으로 리턴! 
"""
   학과   이름   학년   학점
0 컴퓨터  아이유   1    1.5
2 컴퓨터  홍길동   3    3.5
4 컴퓨터  신사임당  3    4.0
"""

display(dept.size())  # 사이즈는 series 때와 똑같음
"""
학과
철학      2
컴퓨터    3
dtype: int64
"""
display(dept.mean()) # 왜 df로 나오나요? 학년도 숫자로 되어 있어서 평균값이 나옴.
                    # 그렇지만 학년을 str로 지정해줘도 df로나옴. 원본 데이터가 df라 df로 리턴
"""
      학점
학과	
철학   2.3
컴퓨터  3.0
"""

그룹핑 반복처리

각각의 그룹에서 반복 처리는 어떻게 하는가?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import numpy as np
import pandas as pd

df = pd.DataFrame({
    '학과': ['컴퓨터', '철학', '컴퓨터', '철학', '컴퓨터'],
    '이름': ['아이유', '김연아', '홍길동', '강감찬', '신사임당'],
    '학년': [1, 2, 3, 2, 3],
    '학점': [1.5, 2.7, 3.5, 1.9, 4.0]
})

display(df)
"""
   학과    이름  학년  학점
0 컴퓨터  아이유   1  1.5
1 철학    김연아  2  2.7
2 컴퓨터  홍길동  3   3.5
3 철학    강감찬  2  1.9
4 컴퓨터  신사임당 3  4.0
"""

for dept, group in df.groupby(df['학과']):
    print(dept)
    display(group) # dept 그룹에 대한 dataframe이 나옴.
"""
i=0 (첫번째 iteration):  
(학과)
철학

  학과   이름   학년   학점
1 철학   김연아   2    2.7
3 철학   강감찬   4    1.9

i=1 (두번째 iteration):
(학과)
컴퓨터

   학과   이름   학년   학점
0 컴퓨터  아이유   1    1.5
2 컴퓨터  홍길동   3    3.5
4 컴퓨터  신사임당  3    4.0
"""
# 이렇게 반복 시킬 수 있음.

2개를 기준으로 그룹핑을 한다면 어떻게 될까?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 2개를 기준으로 그룹핑을 한다면???
for (dept, year), group in df.groupby([df['학과'], df['학년']]):
    print(dept, year)
    display(group)
"""
i=0 (첫번째 iteration):
(학과) (학년)
 철학     2

  학과   이름   학년   학점
1 철학   김연아   2    2.7
3 철학   강감찬   2    1.9


i=1 (두번째 iteration):
(학과) (학년)
 컴퓨터   1
 
   학과   이름   학년   학점
0  컴퓨터 아이유   1    1.5

i=2 (세번째 iteration):
(학과) (학년)
 컴퓨터   3
  
   학과   이름   학년   학점
2 컴퓨터  홍길동   3    3.5
4 컴퓨터  신사임당  3    4.0
"""

이렇게 groupby인자로 나왔던 학과학년 별로 나뉘어서 반복문이 수행된다.

그리고 해당 그룹에 속한 멤버들을 dataframe으로 보여준다.

우선 그룹핑은 여기까지..

끄읏. 👋

This post is licensed under CC BY 4.0 by the author.

python Pandas (10) DataFrame 특정값 처리 (이상치, 결치)

python Pandas (12) DataFrame Duplicates 중복값 제거

Comments powered by Disqus.