ํŒŒ์ด์ฌ ๋งˆ์Šคํ„ฐํ•˜๊ธฐ : Group By ํ•จ์ˆ˜

Posted by Euisuk's Dev Log on May 9, 2023

ํŒŒ์ด์ฌ ๋งˆ์Šคํ„ฐํ•˜๊ธฐ : Group By ํ•จ์ˆ˜

์›๋ณธ ๊ฒŒ์‹œ๊ธ€: https://velog.io/@euisuk-chung/ํŒŒ์ด์ฌ-๋งˆ์Šคํ„ฐํ•˜๊ธฐ-GROUP-BY

ํŒŒ์ด์ฌ ํŒ๋‹ค์Šค ์‹ฌํ™”

ํŒ๋‹ค์Šค(Pandas)์—์„œ Group By๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋ฃนํ™”ํ•˜๊ณ  ๊ทธ๋ฃนํ™”๋œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋Š”๋ฐ ๋งค์šฐ ์œ ์šฉํ•œ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

์ด๋ฒˆ ํฌ์ŠคํŠธ์—์„œ๋Š” Python์—์„œ Group By์˜ ๊ฐœ๋…๊ณผ ํ™œ์šฉ ์˜ˆ์ œ์— ๋Œ€ํ•ด ๋‹ค๋ฃจ์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Group By๋ž€?

Group By๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋ฃนํ™”ํ•˜๊ณ  ๊ทธ๋ฃนํ™”๋œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

Group By๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ ๋” ์‰ฝ๊ฒŒ ๋ถ„์„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Pandas์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ˜•ํƒœ๋กœ Group By๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

1
df.groupby('๊ทธ๋ฃนํ™”ํ•  ์—ด ์ด๋ฆ„')

์œ„ ์ฝ”๋“œ๋Š” df ๋ฐ์ดํ„ฐํ”„๋ ˆ์ž„์„ ๊ทธ๋ฃนํ™”ํ•  ์—ด ์ด๋ฆ„์œผ๋กœ ๊ทธ๋ฃนํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ ๊ทธ๋ฃนํ™”๋œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด ์›ํ•˜๋Š” ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Group By์˜ ํ™œ์šฉ ์˜ˆ์ œ

1. ๊ทธ๋ฃนํ™”๋œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ํ†ต๊ณ„ ์ •๋ณด ๊ตฌํ•˜๊ธฐ

๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค.

1
2
3
4
5
6
7
import pandas as pd
import numpy as np

data = {'ํ•™๋…„': ['1ํ•™๋…„', '1ํ•™๋…„', '2ํ•™๋…„', '2ํ•™๋…„', '3ํ•™๋…„', '3ํ•™๋…„', '3ํ•™๋…„'], 
        '์„ฑ๋ณ„': ['๋‚จ', '์—ฌ', '๋‚จ', '์—ฌ', '๋‚จ', '์—ฌ', '์—ฌ'], 
        '์˜์–ด ์„ฑ์ ': [80, 90, 70, 60, 85, 95, 75]}
df = pd.DataFrame(data)

df

์ด์ œ ํ•™๋…„์„ ๊ธฐ์ค€์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋ฃนํ™”ํ•˜๊ณ , ๊ทธ๋ฃนํ™”๋œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด ์˜์–ด ์„ฑ์ ์˜ ํ‰๊ท , ์ตœ์†Œ๊ฐ’, ์ตœ๋Œ€๊ฐ’ ๋“ฑ์˜ ๊ธฐ๋ณธ ํ†ต๊ณ„ ์ •๋ณด๋ฅผ ๊ตฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

1
2
3
grouped = df.groupby('ํ•™๋…„')
result = grouped['์˜์–ด ์„ฑ์ '].agg(['mean', 'min', 'max', 'count'])
print(result)

์œ„ ์ฝ”๋“œ๋Š” ํ•™๋…„์„ ๊ธฐ์ค€์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋ฃนํ™”ํ•˜๊ณ , ๊ทธ๋ฃนํ™”๋œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด ์˜์–ด ์„ฑ์ ์˜ ํ‰๊ท , ์ตœ์†Œ๊ฐ’, ์ตœ๋Œ€๊ฐ’, ๊ฐœ์ˆ˜ ๋“ฑ์˜ ๊ธฐ๋ณธ ํ†ต๊ณ„ ์ •๋ณด๋ฅผ ๊ตฌํ•ฉ๋‹ˆ๋‹ค. ์ถœ๋ ฅ ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

result

2. ๊ทธ๋ฃนํ™”๋œ ๋ฐ์ดํ„ฐ์˜ ์‹œ๊ฐํ™”

๊ทธ๋ฃนํ™”๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์‹œ๊ฐํ™”ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค.

1
2
3
4
data = {'Location': ['Seoul', 'Seoul', 'Seoul', 'Geongi', 'Geongi', 'Geongi', 'Incheon', 'Incheon', 'Incheon'], 
        'Year': [2018, 2019, 2020, 2018, 2019, 2020, 2018, 2019, 2020], 
        'Population': [9700000, 9800000, 9900000, 13000000, 13500000, 14000000, 2900000, 3000000, 3100000]}
df = pd.DataFrame(data)

df

์ด์ œ ์ง€์—ญ์„ ๊ธฐ์ค€์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋ฃนํ™”ํ•˜๊ณ , ๊ทธ๋ฃนํ™”๋œ ๋ฐ์ดํ„ฐ์˜ ์ธ๊ตฌ ์ •๋ณด๋ฅผ ๋ง‰๋Œ€๊ทธ๋ž˜ํ”„๋กœ ์‹œ๊ฐํ™”ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

1
2
3
4
5
6
7
8
9
import matplotlib.pyplot as plt
import warnings

%matplotlib inline

grouped = df.groupby('Location')
result = grouped['Population'].sum()
result.plot(kind='bar')
plt.show()

์œ„ ์ฝ”๋“œ๋Š” ์ง€์—ญ์„ ๊ธฐ์ค€์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋ฃนํ™”ํ•˜๊ณ , ๊ทธ๋ฃนํ™”๋œ ๋ฐ์ดํ„ฐ์˜ ์ธ๊ตฌ ์ •๋ณด๋ฅผ ๋ง‰๋Œ€๊ทธ๋ž˜ํ”„๋กœ ์‹œ๊ฐํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ถœ๋ ฅ ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

viz

์œ„ ๊ทธ๋ž˜ํ”„์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด, ์„œ์šธ๊ณผ ๊ฒฝ๊ธฐ ์ง€์—ญ์˜ ์ธ๊ตฌ๊ฐ€ ์ฆ๊ฐ€ํ•˜๊ณ  ์žˆ๊ณ , ์ธ์ฒœ ์ง€์—ญ์€ ์ƒ๋Œ€์ ์œผ๋กœ ์ธ๊ตฌ ์ฆ๊ฐ€์œจ์ด ๋‚ฎ์€ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

3. ๊ทธ๋ฃนํ™”๋œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์—ฐ์‚ฐ

groupby() ํ•จ์ˆ˜๋Š” ๊ทธ๋ฃนํ™”๋œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค.

1
2
3
4
5
6
7
import pandas as pd
import numpy as np

data = {'ํ•™๋…„': ['1ํ•™๋…„', '1ํ•™๋…„', '2ํ•™๋…„', '2ํ•™๋…„', '3ํ•™๋…„', '3ํ•™๋…„', '3ํ•™๋…„'], 
        '์„ฑ๋ณ„': ['๋‚จ', '์—ฌ', '๋‚จ', '์—ฌ', '๋‚จ', '์—ฌ', '์—ฌ'], 
        '์˜์–ด ์„ฑ์ ': [80, 90, 70, 60, 85, 95, 75]}
df = pd.DataFrame(data)

df

์ด์ œ ํ•™๋…„์„ ๊ธฐ์ค€์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋ฃนํ™”ํ•˜๊ณ , ๊ทธ๋ฃนํ™”๋œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด ์˜์–ด ์„ฑ์ ์˜ ํ‰๊ท ์„ ๊ตฌํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

1
2
3
grouped = df.groupby('ํ•™๋…„')
result = grouped['์˜์–ด ์„ฑ์ '].mean()
print(result)

์œ„ ์ฝ”๋“œ๋Š” ํ•™๋…„์„ ๊ธฐ์ค€์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋ฃนํ™”ํ•˜๊ณ , ๊ทธ๋ฃนํ™”๋œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด ์˜์–ด ์„ฑ์ ์˜ ํ‰๊ท ์„ ๊ตฌํ•ฉ๋‹ˆ๋‹ค. ์ถœ๋ ฅ ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

1
2
3
4
5
ํ•™๋…„
1ํ•™๋…„    85.0
2ํ•™๋…„    65.0
3ํ•™๋…„    85.0
Name: ์˜์–ด ์„ฑ์ , dtype: float64

4. ๊ทธ๋ฃนํ™”๋œ ๋ฐ์ดํ„ฐ์˜ ํ”ผ๋ฒ— ํ…Œ์ด๋ธ” ์ƒ์„ฑ

pivot_table() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ทธ๋ฃนํ™”๋œ ๋ฐ์ดํ„ฐ์˜ ํ”ผ๋ฒ— ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค.

1
2
3
4
5
data = {'๊ตญ๊ฐ€': ['ํ•œ๊ตญ', 'ํ•œ๊ตญ', '๋ฏธ๊ตญ', '๋ฏธ๊ตญ', '์ผ๋ณธ', '์ผ๋ณธ', 'ํ•œ๊ตญ', '๋ฏธ๊ตญ', '์ผ๋ณธ'], 
        '์„ฑ๋ณ„': ['๋‚จ', '์—ฌ', '๋‚จ', '์—ฌ', '๋‚จ', '์—ฌ', '๋‚จ', '์—ฌ', '๋‚จ'], 
        'ํ‚ค': [170, 160, 180, 170, 165, 155, 175, 185, 175], 
        '๋ชธ๋ฌด๊ฒŒ': [70, 60, 80, 65, 70, 50, 75, 85, 70]}
df = pd.DataFrame(data)

df

์ด์ œ ๊ตญ๊ฐ€์™€ ์„ฑ๋ณ„์„ ๊ธฐ์ค€์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋ฃนํ™”ํ•˜๊ณ , ํ‚ค์™€ ๋ชธ๋ฌด๊ฒŒ์— ๋Œ€ํ•œ ํ”ผ๋ฒ— ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

1
2
table = pd.pivot_table(df, index=['๊ตญ๊ฐ€', '์„ฑ๋ณ„'], values=['ํ‚ค', '๋ชธ๋ฌด๊ฒŒ'], aggfunc=np.mean)
print(table)

์œ„ ์ฝ”๋“œ๋Š” ๊ตญ๊ฐ€์™€ ์„ฑ๋ณ„์„ ๊ธฐ์ค€์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋ฃนํ™”ํ•˜๊ณ , ํ‚ค์™€ ๋ชธ๋ฌด๊ฒŒ์— ๋Œ€ํ•œ ํ‰๊ท ๊ฐ’์„ ๊ตฌํ•œ ๋’ค, ์ด๋ฅผ ํ”ผ๋ฒ— ํ…Œ์ด๋ธ”๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ถœ๋ ฅ ๊ฒฐ๊ณผ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

pivot

์œ„ ํ”ผ๋ฒ— ํ…Œ์ด๋ธ”์„ ๋ณด๋ฉด, ๊ตญ๊ฐ€์™€ ์„ฑ๋ณ„ ๊ธฐ์ค€์œผ๋กœ ๊ทธ๋ฃนํ™”๋œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด ํ‚ค์™€ ๋ชธ๋ฌด๊ฒŒ์— ๋Œ€ํ•œ ํ‰๊ท ๊ฐ’์„ ๊ตฌํ•œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ฒ˜๋Ÿผ Group By์™€ pivot_table์„ ์กฐํ•ฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ ํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ ๋ถ„์„์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฒฐ๋ก 

์œ„ ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด Python์—์„œ Group By์˜ ๊ฐœ๋…๊ณผ ํ™œ์šฉ ์˜ˆ์ œ์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. Group By๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ๊ทธ๋ฃนํ™”ํ•˜๊ณ  ๊ทธ๋ฃนํ™”๋œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋Š”๋ฐ ๋งค์šฐ ์œ ์šฉํ•œ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. Pandas์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ ๋” ์‰ฝ๊ฒŒ ๋ถ„์„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.



-->