[Pandas] drop_duplicates / duplicated
Pandas unique / nunique, Pandas drop_duplicates, Pandas duplicated, 중복 제거 pandas
정의
duplicated(): 각 행이 중복인지 boolean Series 반환drop_duplicates(): 중복 행 제거 후 DataFrame 반환
Pandas unique / nunique 와는 다르다. 그건 Series 의 고유값 추출, 이건 행 단위 처리.
기본
python
import pandas as pd
df = pd.DataFrame({
'name': ['Alice','Bob','Alice','Charlie','Bob'],
'age': [30, 25, 30, 35, 25],
})
print(df.duplicated().tolist())
print('---')
print(df.drop_duplicates()) 결과
[False, False, True, False, True]
---
name age
0 Alice 30
1 Bob 25
3 Charlie 35subset (특정 컬럼만)
df.drop_duplicates(subset=['email']) # email 기준 중복
df.drop_duplicates(subset=['name', 'phone']) # 두 컬럼 조합
keep (어느 행을 남길지)
| keep | 동작 |
|---|---|
'first' (기본) | 첫 등장 유지 |
'last' | 마지막 등장 유지 |
False | 모든 중복 제거 (단일 등장만 남김) |
df.drop_duplicates(keep='first')
df.drop_duplicates(keep='last')
df.drop_duplicates(keep=False) # 단 한 번만 나오는 행만
python
import pandas as pd
df = pd.DataFrame({'name': ['A','B','A','C','B']})
print(df.drop_duplicates(keep=False)) # A, B 가 모두 제거됨 결과
name
3 Cduplicated 활용
df[df.duplicated()] # 중복 행만
df[df.duplicated(keep=False)] # 중복된 모든 행 (원본 포함)
df['is_dup'] = df.duplicated('email') # boolean 컬럼 추가
df.duplicated().sum() # 중복 행 개수
index 다루기
df.drop_duplicates() # 원래 index 유지
df.drop_duplicates().reset_index(drop=True) # 0,1,2,... 재배치
그룹별 첫 번째 / 마지막 행
drop_duplicates 는 빠른 그룹별 첫/마지막 선택 idiom.
# 각 user 의 가장 최근 주문
df.sort_values('date', ascending=False).drop_duplicates('user_id')
# 각 user 의 첫 주문
df.sort_values('date').drop_duplicates('user_id')
groupby('user_id').head(1) 보다 약간 빠를 때가 있다.
SQL 비교
-- DISTINCT
SELECT DISTINCT name, age FROM table
-- pandas: df[['name','age']].drop_duplicates()
-- 중복 제거 후 첫 번째 (window function)
SELECT * FROM table
WHERE id IN (
SELECT MIN(id) FROM table GROUP BY user_id
)
-- pandas: df.sort_values('id').drop_duplicates('user_id')
함정
1. NaN 의 중복 처리
df = pd.DataFrame({'x': [1, 1, None, None]})
df.duplicated() # [False, True, False, True]
# NaN == NaN 이 일반적으로 False 인데, duplicated 는 NaN 도 같은 것으로 취급
2. 컬럼 순서
df.drop_duplicates(['a', 'b']) # (a, b) 조합으로 비교
df.drop_duplicates(['b', 'a']) # 결과는 같음, 순서 무관
3. inplace=True 의 함정
df.drop_duplicates(inplace=True) # 옛 코드
df = df.drop_duplicates() # 권장 (명시성)
💬 댓글