본문 바로가기
데이터 분석/데이터 전처리

[Pandas] 35. 데이터 구간 나누기 (feat. cut, qcut)

by 부자 꽁냥이 2023. 1. 17.

안녕하세요~ 꽁냥이에요. 데이터 분석을 하다 보면 데이터를 특정 칼럼값을 기준으로 구간을 나누어야 할 때가 있는데요. Pandas에서 제공하는 cut과 qcut을 이용하면 쉽게 구간을 나눌 수 있어요. 이번 포스팅에서는 Pandas에서 cut과 qcut 사용법을 알아보고 이를 응용하는 방법도 알아보려고 합니다.


   데이터 구간 나누기 (feat. cut, qcut)

1) 데이터를 구간 길이에 따라 나누어 보자 : cut

a. 기본 사용법

데이터를 구간 길이에 따라 나눌 때에는 cut을 사용합니다. cut 함수의 사용법은 다음과 같습니다.

 

cut( array, bins, labels)

 

cut 함수는 나누고자하는 숫자값을 포함하는 배열을 첫 번째 인자로 받습니다. bins는 나누고자 하는 방식인데 bins에 양의 정수를 넣어주면 데이터의 최소값과 최대값으로 이루어진 전체 구간을 정수 개수만큼 등간격으로 나누어줍니다. bins 배열을 넣어줄 수도 있는데 이때에는 배열이 오름차순으로 정렬되어 있어야 합니다. 배열을 넣어주면 배열의 인접한 값을 이용하여 구간을 만들어 줍니다. labels는 구간 명칭을 지정해 줄 수 있습니다. 

 

지금까지 이해못해도 코드를 보면 금방 이해하실 수 있을 거예요. 먼저 1~8까지 데이터를 3등분 해보겠습니다.

 

import pandas as pd
import numpy as np

a = np.array([1,2,3,4,5,6,7,8]) ## 데이터
cut = pd.cut(a, bins=3) ## 데이터를 최소 최대 구간으로 3등분한다.
cut

 

위 코드를 실행하면 아래와 같이 각 데이터가 어느 구간에 속하는지 알려줍니다. 구간은 (0.993, 3.333], (3.333, 5.667], (5.667, 8] 이렇게 세 구간이 만들어졌습니다. 이때 구간의 최소값 0.993는 데이터의 최소값 1과 다르다는 사실을 주목하세요. 이는 가장 왼쪽 구간 최소값을 조금 더 작게 해서 데이터의 최소값을 포함하기 위함입니다.

 

 

이번에는 bins에 배열을 넣어봅시다.

 

a = np.array([1,2,3,4,5,6,7,8])  ## 데이터
cut = pd.cut(a, bins=[0, 2, 4, 8]) ## 데이터를 (0, 2], (2, 4], (4, 8] 구간으로 쪼갠다.
cut

 

위 코드를 실행하면 아래와 같이 bins에 넣어준 배열의 인접값을 이용하여 구간을 만들어줍니다.

 

 

이때 구간에 들어가는 데이터 개수와 상대도수를 확인하려면 describe 메서드를 사용하면 됩니다.

 

cut.describe()

 

 

이때 categories 인덱스에 구간이 아닌 라벨을 설정할 수 있는데 이는 cut 함수의 labels인자를 통해서 설정할 수 있습니다.

 

a = np.array([1,2,3,4,5,6,7,8])  ## 데이터
cut = pd.cut(a, bins=[0, 2, 4, 8], labels=['bad', 'med', 'good']) ## 데이터를 (0, 2], (2, 4], (4, 8] 구간으로 쪼갠다.
cut.describe()

 


describe 사용 시 주의사항

describe 사용 할때 데이터를 리스트 또는 넘파이(Numpy) 배열로 사용하면 위 그림처럼 데이터프레임 형태로 나오지만 아래와 같이 Pandas Series 객체를 사용한다면 위와 다른 결과가 나오게 됩니다. 이유는 잘 모르겠습니다.

 

a = pd.Series([1,2,3,4,5,6,7,8])  ## 데이터
cut = pd.cut(a, bins=[0, 2, 4, 8]) ## 데이터를 (0, 2], (2, 4], (4, 8] 구간으로 쪼갠다.
cut.describe()

 


b. 응용하기

이번엔 앞에서 배운 내용을 조금 응용해볼까 해요. 학생들의 성적을 높은 순서대로 A~E의 등급을 주려고 해요. 먼저 성적 데이터를 만들어보겠습니다.

 

df = pd.DataFrame()
df['name'] = ['Alice', 'Amy', 'John', 'Michael', 'Tom', 'Carry', 'Cabin']
df['score'] = [20, 35, 14, 90, 100, 66, 77]

 

이제 학생별로 점수 구간과 구간별 등급을 매겨줄 거예요.

 

df['interval'] = pd.cut(df['score'], 5)
df['rank'] = pd.cut(df['score'], 5, labels=['A', 'B', 'C', 'D', 'E'][::-1])
df

 

데이터프레임을 열어보면 아래와 같이 학생 별로 점수 구간과 구간별 등급이 추가된 것을 알 수 있어요.

 


2) 데이터를 빈도수에 따라 나누어 보자 : qcut

a. 기본 사용법

데이터를 빈도수에 따라 나눌 때에는 qcut을 사용합니다. qcut함수의 사용법은 다음과 같습니다.

 

qcut( array, q, labels)

 

qcut 함수는 cut과 비슷한 방법으로 사용합니다. cut과 다른 점은 cut에서 bins의 역할을 qcut에서는 q인자가 하고 있다는 것입니다. q에 양의 정수를 넣는다면 그 정수 개수만큼의 구간을 생성하며 각 구간에는 동일한 데이터 개수가 들어가게 됩니다. 만약 데이터 개수가 100개고 q에 4를 넣는다면 각 구간별로 동일하게 25(=100/4) 개수만큼 들어가게 됩니다. 만약 배열을 넣는다면 그 배열은 오름차순으로 정렬되어 있어야 하며 인접한 값을 분위수로 취급하여 구간을 만들게 됩니다.

 

지금까지 이해가 안 된다 해도 코드를 보면 금방 이해할 수 있습니다. 먼저 0~1 사이의 난수 100개를 생성한 뒤 데이터를 3 등분하는 구간을 구해보겠습니다.

 

np.random.seed(100)
a = np.random.uniform(0,1,100)  ## 데이터
cut = pd.qcut(a, q=3) ## 데이터개수를 3등분하는 구간 생성
cut.describe()

 

위 코드를 실행하면 3개의 구간이 생성된 것을 알 수 있으며 각 구간별로 균등하게(100이 3으로 정확히 안 나누어지므로 맨 첫 구간에는 34개를 포함) 데이터가 포함된 것을 알 수 있습니다.

 

 

이번엔 q인자에 배열을 넣어서 데이터 구간을 만들어 보겠습니다. 아래 코드는 데이터를 (최소값 ~ 제1 사분위수], (제1 사분위수 ~ 제3 사분위수], (제3 사분위수 ~ 최대값] 구간을 생성합니다.

 

np.random.seed(100)
a = np.random.uniform(0,1,100)  ## 데이터
cut = pd.qcut(a, q=[0, 0.25, 0.75, 1]) 
cut.describe()

 

위 코드를 실행하면 아래와 같이 데이터가 25%, 50%, 25%가 포함되도록 구간이 설정된 것을 알 수 있습니다. 이때 첫 번째 구간의 최소값은 0.00372인데 이는 데이터 최소값보다 좀 더 작습니다. 이유는 데이터 최소값까지 포함시키게 하기 위함입니다.

 

 

b. 응용하기

여기서는 데이터를 특정 칼럼으로 정렬한 뒤 데이터 개수 기준으로 5 등분하여 그룹을 만들어주려고 합니다. 먼저 100개의 데이터를 만들어줍니다.

 

np.random.seed(100)
df = pd.DataFrame()
df['a'] = np.random.uniform(0,1,100)
df['b'] = np.random.choice(['a', 'b', 'c', 'd'], 100)

 

이때 칼럼 a를 기준으로 오름차순으로 정렬한 뒤 각 데이터를 5 등분해 보겠습니다. 또한 각 그룹의 명칭도 지정해 주었습니다.

 

df = df.sort_values('a') ## 오름차순 정렬
labels=['group1', 'group2', 'group3', 'group4', 'group5'] ## 그룹 명칭
df['group'] = pd.qcut(range(len(df)), q=5, labels=labels)
df

 

위 코드를 실행하면 아래와 같이 a에 대하여 오름차순으로 정렬하고 그룹이 잘 할당된 것을 알 수 있습니다.

 


이번에 데이터 분석을 하면서 구간을 나눠야 할 필요가 있었는데 Pandas에서 cut과 qcut을 제공하는 것을 알게 되어 유용하게 사용했는데요. 이때 사용한 방법을 까먹지 않기 위해서 포스팅하게 되었어요. 부디 이번 포스팅이 많은 분들께 도움이 되셨으면 좋겠습니다. 다음에도 좋은 주제로 찾아뵙겠습니다~ 안녕히 계세요!


댓글


맨 위로