본문으로 건너뛰기
김신건의 로그

[Pandas] value_counts

· 수정 · 📖 약 1분 · 350자/단어 #python #pandas #value_counts #frequency
Pandas value_counts, Series value_counts, 빈도수 pandas

정의

Series.value_counts() 는 각 고유값의 등장 빈도 를 내림차순 Series 로 반환. SQL 의 GROUP BY ... ORDER BY count DESC.

pandas 1.1+ 부터는 DataFrame.value_counts() 도 가능 (여러 컬럼 조합).

기본

python
import pandas as pd
s = pd.Series(['A', 'B', 'A', 'C', 'B', 'A', 'B'])
print(s.value_counts())
결과
A    3
B    3
C    1
Name: count, dtype: int64
valuecount
A3
B3
C1

옵션

s.value_counts(normalize=True)    # 비율 (sum to 1)
s.value_counts(ascending=True)     # 오름차순
s.value_counts(dropna=False)       # NaN 도 카운트
s.value_counts(bins=5)             # 수치형, 5 개 구간으로 binning

normalize

python
import pandas as pd
s = pd.Series(['A', 'B', 'A', 'C', 'B', 'A', 'B'])
print(s.value_counts(normalize=True))
결과
A    0.428571
B    0.428571
C    0.142857
Name: proportion, dtype: float64

비율 → 분포 분석에 유용.

DataFrame.value_counts (다중 컬럼)

df.value_counts(['city', 'plan'])
# (city, plan) 조합의 빈도
python
import pandas as pd
df = pd.DataFrame({
  'city': ['Seoul','Busan','Seoul','Busan','Seoul'],
  'plan': ['pro','basic','pro','basic','basic'],
})
print(df.value_counts())
결과
city   plan
Seoul  pro      2
Busan  basic    2
Seoul  basic    1
Name: count, dtype: int64

MultiIndex Series 결과.

bins (수치형 분포)

ages = pd.Series([22, 25, 31, 35, 42, 55, 18, 29])
ages.value_counts(bins=4)
# (17.999, 27.25]    3
# (27.25, 36.5]      3
# (36.5, 45.75]      1
# (45.75, 55.0]      1

자동으로 구간 분할, Pandas cut / qcut 의 quick version.

SQL 비교

SELECT value, COUNT(*) AS count
FROM table
GROUP BY value
ORDER BY count DESC

s.value_counts() 한 줄과 같다.

활용 패턴

상위 N 개 카테고리

top10 = s.value_counts().head(10)

빈도가 낮은 카테고리 묶기

counts = df['category'].value_counts()
rare = counts[counts < 10].index
df['category'] = df['category'].where(~df['category'].isin(rare), 'OTHER')

빈도 시각화

df['category'].value_counts().plot(kind='bar')

value_counts vs groupby + size

s.value_counts()                          # ↓ 같은 결과
df.groupby('city').size().sort_values(ascending=False)

value_counts 가 더 짧고 명시적.

함정

1. NaN 기본 제외

s.value_counts()                          # NaN 제외
s.value_counts(dropna=False)              # NaN 포함

2. category dtype 의 차이

s = pd.Series(['A','B','A'], dtype='category')
s.value_counts()                          # 등장한 카테고리만
# Categorical 의 categories 에 정의됐지만 등장 안 한 값은?
# pandas 2.x: observed=False 로 포함 가능

3. Series 가 아닌 DataFrame 에 호출

df.value_counts()       # 모든 컬럼 조합의 빈도 (1.1+)
df.value_counts('col')  # 단일 컬럼

빈도 분석 흐름

flowchart LR
    Raw["Series / DataFrame"] --> VC["value_counts()"]
    VC --> Count["카운트 Series"]
    Count --> A["normalize=True: 비율"]
    Count --> B["head(N): Top-N"]
    Count --> C["plot(): 시각화"]

카테고리 통합 패턴

# 빈도 낮은 카테고리를 'OTHER' 로 통합
counts = df['platform'].value_counts()
rare = counts[counts < 100].index
df['platform'] = df['platform'].where(~df['platform'].isin(rare), 'OTHER')

# long-tail 확인
df['platform'].value_counts()

특정 임계값 이하의 카테고리를 묶어 long-tail 처리.

비율 + 누적 분포

vc = df['country'].value_counts(normalize=True)
cumulative = vc.cumsum()
# 상위 5개 국가가 전체의 몇 % 커버?
print(cumulative.head(5))
print(f"상위 5개국 커버율: {cumulative.iloc[4]:.1%}")

파레토 분석 (상위 20% 가 80% 비율 커버) 패턴.

빈도 시각화

# 수직 막대 차트
df['plan'].value_counts().plot(kind='bar', title='Plan 분포')

# 수평 막대 (카테고리 많을 때 가독성)
df['country'].value_counts().head(20).plot(kind='barh')

# 파이 차트
df['tier'].value_counts().plot(kind='pie', autopct='%1.1f%%')

value_counts 결과를 DataFrame 에 join

vc = df['city'].value_counts().rename('city_count')
df = df.join(vc, on='city')
# 각 row 에 해당 도시의 전체 빈도 추가

분포 이상 탐지

# 예상 외 카테고리 확인
expected = {'active', 'inactive', 'pending'}
actual = set(df['status'].unique())
unexpected = actual - expected
if unexpected:
    print(f"예상 외 값: {unexpected}")

# 단일 값이 지나치게 지배적
vc = df['status'].value_counts(normalize=True)
if vc.iloc[0] > 0.9:
    print("경고: 단일 값이 90% 초과")

관련 함수 비교

함수반환정렬 기준
value_counts()count Series빈도 내림차순
groupby + size()count Series키 오름차순
groupby + count()non-null count키 오름차순
unique()고유값 배열등장 순
nunique()고유값 개수N/A

value_counts 가 가장 간결. 정렬이나 추가 집계가 필요하면 groupby.

참고

이 글의 용어 (6개)
[Pandas] agg / aggregatepandas
정의 는 여러 집계 함수를 한 번에 적용 한다. , , 모두에서 사용 가능. 는 같은 함수의 별칭. agg 처리 흐름 사용 상황 | 상황 | 패턴 | |:---|:---| | 전…
[Pandas] Categoricalpandas
정의 Categorical 은 제한된 고유값 만 가질 수 있는 dtype. 내부적으로 정수 코드로 저장되어 메모리 절약 과 속도 향상 을 동시에 달성한다. 고유값 수가 적고(lo…
[Pandas] cut / qcutpandas
정의 - : 값 기반 binning (구간을 직접 지정) - : 빈도 기반 binning (분위수로 같은 크기) 연속형 변수를 범주형으로 변환. ML 의 feature engin…
[Pandas] drop_duplicates / duplicatedpandas
정의 - : 각 행이 중복인지 boolean Series 반환 - : 중복 행 제거 후 DataFrame 반환 와는 다르다. 그건 Series 의 고유값 추출, 이건 행 단위 처…
[Pandas] groupbypandas
정의 는 데이터를 그룹으로 나누고 (split), 각 그룹에 함수를 적용 (apply), 결과를 합쳐 (combine) 새 DataFrame 으로 만드는 split-apply-c…
[Pandas] Seriespandas
정의 는 1차원 레이블 배열. NumPy + 의 결합. 의 한 열이 곧 Series. dict-like (key = index label) 이자 list-like (순서 있는 배…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기