Python/NumPy | Pandas

[Python] Pandas - 피봇테이블과 그룹분석 2

비번변경 2022. 12. 31. 17:33

그룹분석

키가 지정하는 조건에 맞는 데이터가 하나 이상으로 데이터 그룹을 이루는 경우, 그룹분석을 사용해 그룹의 특성을 확인해야 한다. 그룹의 특성은 미리 지정한 연산을 이용해 계산한 그룹의 대푯값으로 한다. Pandas에서는 다음과 같은 방식으로 그룹분석을 수행한다.

 

1. 분석할 시리즈나 데이터 프레임에 groupby 함수를 실행하여 그룹화를 한다.

2. 그룹화한 데이터에 그룹연산을 수행한다.

 

 

groupby

데이터를 그룹 별로 분류하는 함수로 열 또는 열의 리스트, 행 인덱스를 매개변수로 전달한다.

groupby 함수는 그룹 데이터를 나타내는 GroupBy 클래스 객체를 반환한다. GroupBy 객체는 그룹변로 연산할 수 있는 그룹연산 함수를 제공한다.

 

 

그룹연산 함수

자주 사용하는 그룹연산 함수는 다음과 같다.

  • size, count : 그룹 데이터의 개수
  • mean, median, min, max : 그룹 데이터의 평균, 중앙값, 최소, 최대
  • sum, prod, std, var, quantile : 그룹 테이터의 합계, 곱, 표준편차, 분산, 사분위수
  • first, last : 그룹 데이터 중 첫번째 데이터와 마지막 데이터
  • agg, aggregate : 사용자 정의 그룹 연산 함수를 생성하여 전달하거나 여러 그룹 연산을 동시에 실행시킬 때 함수 이름을 문자열 리스트로 전달한다.
def peak_to_peak_ratio(x):
    return x.max() / x.min()

iris.groupby(iris.species).agg(peak_to_peak_ratio)

# 실행 결과
            sepal_length  sepal_width  petal_length  petal_width
species                                                         
setosa          1.348837     1.913043      1.900000     6.000000
versicolor      1.428571     1.700000      1.700000     1.800000
virginica       1.612245     1.727273      1.533333     1.785714
  • describe : 다양한 기술 통계 값을 포함한 데이터프레임을 반환한다.
iris.groupby(iris.species).describe().T

# 실행 결과
species                setosa  versicolor  virginica
sepal_length count  50.000000   50.000000  50.000000
             mean    5.006000    5.936000   6.588000
             std     0.352490    0.516171   0.635880
             min     4.300000    4.900000   4.900000
             25%     4.800000    5.600000   6.225000
             50%     5.000000    5.900000   6.500000
             75%     5.200000    6.300000   6.900000
             max     5.800000    7.000000   7.900000
sepal_width  count  50.000000   50.000000  50.000000
             mean    3.428000    2.770000   2.974000
             std     0.379064    0.313798   0.322497
             min     2.300000    2.000000   2.200000
             25%     3.200000    2.525000   2.800000
             50%     3.400000    2.800000   3.000000
             75%     3.675000    3.000000   3.175000
             max     4.400000    3.400000   3.800000
petal_length count  50.000000   50.000000  50.000000
             mean    1.462000    4.260000   5.552000
             std     0.173664    0.469911   0.551895
             min     1.000000    3.000000   4.500000
             25%     1.400000    4.000000   5.100000
             50%     1.500000    4.350000   5.550000
             75%     1.575000    4.600000   5.875000
             max     1.900000    5.100000   6.900000
...
             min     0.100000    1.000000   1.400000
             25%     0.200000    1.200000   1.800000
             50%     0.200000    1.300000   2.000000
             75%     0.300000    1.500000   2.300000
             max     0.600000    1.800000   2.500000
  • apply : 원하는 그룹 연산이 없을 때 사용한다.
def top3_petal_length(df):
    return df.sort_values(by="petal_length", ascending=False)[:3]

iris.groupby(iris.species).apply(top3_petal_length)

# 실행 결과
                sepal_length  sepal_width  petal_length  petal_width  species
species                                                                
setosa     24            4.8          3.4           1.9          0.2   setosa
           44            5.1          3.8           1.9          0.4   setosa
           23            5.1          3.3           1.7          0.5   setosa
versicolor 83            6.0          2.7           5.1          1.6   versicolor
           77            6.7          3.0           5.0          1.7   versicolor
           72            6.3          2.5           4.9          1.5   versicolor
virginica  118           7.7          2.6           6.9          2.3   virginica
           117           7.7          3.8           6.7          2.2   virginica
           122           7.7          2.8           6.7          2.0   virginica
  • transform : 그룹 별 계산을 통해 데이터 자체를 변형한다.
def q3cut(s):
    return pd.qcut(s, 3, labels=["소", "중", "대"]).astype(str)

iris["petal_length_class"] = iris.groupby(iris.species).petal_length.transform(q3cut)
iris[["petal_length", "petal_length_class"]].tail(10)


# 실행 결과
     petal_length petal_length_class
140           5.6                  중
141           5.1                  소
142           5.1                  소
143           5.9                  대
144           5.7                  중
145           5.2                  소
146           5.0                  소
147           5.2                  소
148           5.4                  중
149           5.1                  소

 

 

예시

아래와 같은 데이터가 있다고 하자.

df2 = pd.DataFrame({
    'key1': ['A', 'A', 'B', 'B', 'A'],
    'key2': ['one', 'two', 'one', 'two', 'one'],
    'data1': [1, 2, 3, 4, 5],
    'data2': [10, 20, 30, 40, 50]
})
df2

# 실행 결과
  key1 key2  data1  data2
0    A  one      1     10
1    A  two      2     20
2    B  one      3     30
3    B  two      4     40
4    A  one      5     50

위 데이터의 key1의 값에 따른 data1의 평균은 다음과 같이 구할 수 있다.

# 데이터 그룹화
g = df2.groupby(df2.key1)
g.groups
g.mean(numeric_only=True)

## 실행 결과
{'A': [0, 1, 4], 'B': [2, 3]}

         data1      data2
key1                     
A     2.666667  26.666667
B     3.500000  35.000000

GroupBy 객체는 groups 속성을 이용해 그룹화된 데이터를 조회할 수 있다. 또한 인덱싱을 이용해 특정 컬럼만 연산할 수도 있다.

df2.groupby(df2.key2)['data2'].sum(numeric_only=True)

# 실행 결과
key2
one    90
two    60
Name: data2, dtype: int64

groupby 함수에 키 리스트를 전달하면 복합 키에 따른 groupby 연산을 수행할 수 있다.

df2.data1.groupby([df2.key1, df2.key2]).first()

# 실행 결과
key1  key2
A     one     1
      two     2
B     one     3
      two     4
Name: data1, dtype: int64

 

.

 

참고 문서