Group by

db를 다룰때 group by를 쓰곤 했는데, pandas에도 비슷한 기능이 있다.

다음과 같은 data frame을 변형해본다.

# data from: 
data = {'group': ['A', 'A', 'A', 'D', 'c',
         'b', 'B', 'C', 'D', 'D', 'd', 'C'],
         'age': [20,25,23,21,24,25,21,28,26,25,23,21],
         'num':[123,45,342,324,35,4523,34,452,3452,324,8567,563]}

df = pd.DataFrame(data)
df

 

groupby 함수를 아래와 같이쓸 수 있다.

df.groupby("group")["num"].sum()

''' 결과
group
A     510
B      34
C    1015
D    4100
b    4523
c      35
d    8567
Name: num, dtype: int64
'''
# 여러개도 가능하다.
h = df.groupby(["group", 'age'])["num"].sum()

''' 결과
group  age
A      20      123
       23      342
       25       45
B      21       34
C      21      563
       28      452
D      21      324
       25      324
       26     3452
b      25     4523
c      24       35
d      23     8567
Name: num, dtype: int64
'''

# 새로 생성된 h는 Series이다.
type(h)
'''
pandas.core.series.Series
'''

# index는 여러개로 잡혀있다.
h.index
'''
MultiIndex([('A', 20),
            ('A', 23),
            ('A', 25),
            ('B', 21),
            ('C', 21),
            ('C', 28),
            ('D', 21),
            ('D', 25),
            ('D', 26),
            ('b', 25),
            ('c', 24),
            ('d', 23)],
           names=['group', 'age'])
 '''

 

새로 생성한 series을 가지고 이것저것 해볼 수 있다.

- unstack: 그룹 풀기

- swaplevel: 그룹 순서 바꾸기

- sum(level=lv): lv번째 인덱스로 묶어 더하기 *deprecated. -> groupby(level=lv).sum()을 쓰길바람.

unh = h.unstack()
'''
age	20	21	23	24	25	26	28
group							
A	123.0	NaN	342.0	NaN	45.0	NaN	NaN
B	NaN	34.0	NaN	NaN	NaN	NaN	NaN
C	NaN	563.0	NaN	NaN	NaN	NaN	452.0
D	NaN	324.0	NaN	NaN	324.0	3452.0	NaN
b	NaN	NaN	NaN	NaN	4523.0	NaN	NaN
c	NaN	NaN	NaN	35.0	NaN	NaN	NaN
d	NaN	NaN	8567.0	NaN	NaN	NaN	NaN
'''

unh.index
''' 원래의 range index가 아닌 group이 index로 잡히는 것을 볼 수 있다.
Index(['A', 'B', 'C', 'D', 'b', 'c', 'd'], dtype='object', name='group')
'''

h.swaplevel()
''' group age 순을 age group 순으로 바꿨다.
age  group
20   A         123
23   A         342
25   A          45
21   B          34
     C         563
28   C         452
21   D         324
25   D         324
26   D        3452
25   b        4523
24   c          35
23   d        8567
Name: num, dtype: int64
'''

h.sum(level=0)
''' 첫번째 index로 묶는다.
group
A     510
B      34
C    1015
D    4100
b    4523
c      35
d    8567
Name: num, dtype: int64
'''

h.groupby(level=1).sum()
''' h.sum(level=1)과 동일하나, pandas는 더 직관적인 groupby를 쓰도록 하고 있다.
age
20     123
21     921
23    8909
24      35
25    4892
26    3452
28     452
Name: num, dtype: int64
'''

 

grouped 상태 사용하기

# groupby만 쓴다면, grouped 상태라고 하며 generator와 같다.
grouped = df.groupby('group')

# for문에 key: value 값으로 그룹별로 순회할 수 있다.
for name,group in grouped:
    print(name)
    print(type(group))
'''
A
<class 'pandas.core.frame.DataFrame'>
B
<class 'pandas.core.frame.DataFrame'>
C
<class 'pandas.core.frame.DataFrame'>
D
<class 'pandas.core.frame.DataFrame'>
b
<class 'pandas.core.frame.DataFrame'>
c
<class 'pandas.core.frame.DataFrame'>
d
<class 'pandas.core.frame.DataFrame'>
'''

# Aggregation도 쓸 수 있다.
grouped.agg(min) # 각각의 그룹 dataframe에 대해 가장 큰 값을 뽑아냄

'''
	age	num
group		
A	20	45 # 하나의 컬럼이 아닌 가장 작은 age와 num임.
B	21	34
C	21	452
D	21	324
b	25	4523
c	24	35
d	23	8567
'''

# 그룹별 각 그룹 내 컬럼의 값을 변경하는 것.
grouped.transform(lambda x: x.min())
'''
	age	num
0	20	45
1	20	45
2	20	45
3	21	324
4	24	35
5	25	4523
6	21	34
7	21	452
8	21	324
9	21	324
10	23	8567
11	21	452
'''

# 그룹을 필터링 할 수도 있다.
# having과 같은 느낌의 filter 함수.
grouped.filter(lambda x: x["num"].max() > 1000)
'''
	group	age	num
3	D	21	324
5	b	25	4523
8	D	26	3452
9	D	25	324
10	d	23	8567
'''

기타 도움 되었던 것들.

value_counts

# 컬럼의 값들의 빈도룰 반환하는 함수.
df[컬럼 이름].value_counts()
'''
칼럼1	200
칼럼2	100
Name 컬럼 이름, dtype: float64
'''

# 빈도를 비율로 구하고 싶다면 normalize값을 주면 된다.
df[컬럼 이름].value_counts(normalize=True)
'''
칼럼1	0.6666
칼럼2	0.3333
Name 컬럼 이름, dtype: float64
'''

 

pd.cut

# pd.cut은 이름에 걸맞게 연속적인 값들을 특정한 값으로 분류할때 쓰인다.
# 예를들면 아래의 경우 (0, 10], (10, 20], (20, 30] 순.
categories = pd.cut(df[컬럼], bins=[0, 10, 20, 30, 40])

회고

pandas에서 제공하는 기능이 많아 이번은 어려웠다.

앞으로 많이 사용해보며 익숙해져야 겠다.

'프로그래밍 > 부스트캠프 AI' 카테고리의 다른 글

DKT - EDA 해보기  (1) 2023.05.06
[level1] preprocess 최적화 (캐싱)  (0) 2023.04.16
Day 5 - CNN, RNN  (0) 2023.03.11
Day 4 - AI Basic  (0) 2023.03.09
Day 2 - 파이썬 oop 및 데이터 다루기  (0) 2023.03.07
2jun0