🟡 pandas 1차 강의 🟡
✅ 기본 구조
🔰 Series
1차원 배열 형태의 자료구조. 값(value)들의 모음에 각각 인덱스(index)라는 이름표가 붙어있는 구조
import pandas as pd
scores = pd.Series([90, 80, 85, 95])
print(scores)
*>>> 출력
0 90
1 80
2 85
3 95
dtype: int64*
subjects = pd.Series([90, 80, 85, 95], index=['국어','영어','수학','과학'])
print(subjects)
print(subjects["수학"]) # 출력 : *85*
print(subjects.values) # 출력 : *[90 80 85 95]*
print(subjects.index) # 출력 : *Index(['국어', '영어', '수학', '과학'], dtype='object')*
*>>> 출력
국어 90
영어 80
수학 85
과학 95
dtype: int64*
🔰 DataFrame
2차원 표 형태의 자료구조로, 행(row)과 열(column)으로 구성
여러 개의 Series가 같은 인덱스를 기준으로 모여 있는 형태
SQL의 테이블과 비슷한 구조이며, 판다스에서 데이터를 다룰 때 가장 많이 사용하는 핵심 객체
✨ 파이썬의 딕셔너리(dict) 로부터 생성 ✨
data = {
'이름': ['Alice', 'Bob', 'Charlie'],
'나이': [25, 30, 35],
'도시': ['New York', 'Los Angeles', 'Chicago']
}
df = pd.DataFrame(data)
print(df)
*>>> 출력
이름 나이 도시
0 Alice 25 New York
1 Bob 30 Los Angeles
2 Charlie 35 Chicago*
print(df.head(n)) # 출력 : 상위 n개 행 표시. n생략시 5개 표시.
print(df.tail(n)) # 출력 : 하위 n개 행 표시. n생략시 5개 표시.
print(df.columns) # 출력 : Index(['이름', '나이', '도시'], dtype='object')
print(df.index) # 출력 : RangeIndex(start=0, stop=3, step=1)
print(df.shape) # 출력 : (3, 3)
print(df.info()) # 각 컬럼의 타입, null 개수 등 정보 출력
print(df.describe()) # 수치형 컬럼들의 통계 요약
>>> 출력
↓ print(df.info())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3 entries, 0 to 2
Data columns (total 3 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 이름 3 non-null object
1 나이 3 non-null int64
2 도시 3 non-null object
dtypes: int64(1), object(2)
memory usage: 200.0+ bytes
None
↓ print(df.describe())
나이
count 3.0
mean 30.0
std 5.0
min 25.0
25% 27.5
50% 30.0
75% 32.5
max 35.0
🔰 판다스 주요 데이터 타입
1) 수치형 (Numeric Types)
- int: 정수형 (예: int8, int16, int32, int64)
- → 메모리 크기에 따라 나뉨 (int64가 기본)
- float: 실수형 (예: float16, float32, float64)
- → 소수점을 포함하는 데이터 (float64가 기본)
📌 활용: 평균, 합계, 표준편차, 수학 연산 가능
2) 문자열/범주형 (Text / Categorical Types)
- object: 문자열, 혹은 혼합된 데이터(숫자+문자 등)를 저장하는 일반 타입(문자열이 들어오면 자동으로 object dtype으로 잡힘)
- string: 판다스 1.0 이후 도입된 전용 문자열 타입
- → object보다 일관성이 있고 문자열 메서드 사용에 안전함
- category: 범주형 데이터 (카테고리) 저장용 특수 타입→ 순서(ordered=True)를 지정하면 크기 비교 가능
- → 고유값을 코드로 매핑해 메모리 절약 & 연산 속도 향상
📌 활용: 성별, 지역, 직업 등 집단을 나타내는 데이터
3) 불리언 (Boolean Type)
- bool: True / False 값 저장
- 최근엔 boolean (nullable) 타입도 있음 → 결측치(NaN)와 함께 사용 가능
📌 활용: 조건 필터링, 마스크 연산
4) 날짜/시간 (Datetime Types)
- datetime64[ns]: 날짜/시간 데이터 (년, 월, 일, 시, 분, 초, 나노초 단위)
- timedelta[ns]: 두 시점 사이의 차이(시간 간격)
- period: 일정한 기간(예: 월별, 연도별)
📌 활용: 시계열 분석, 날짜 인덱스, 리샘플링
5) 결측치/특수값
- NaN: 수치형에서의 결측치 (Not a Number)
- NaT: 날짜형에서의 결측치 (Not a Time)
- None: 파이썬 기본 결측값 (object 컬럼에서 보통 NaN처럼 처리됨)
dtype 확인 & 변환
- 확인: df.dtypes, df.info()
- 변환: astype() 메서드 활용
df['age'] = df['age'].astype('int')
df['gender'] = df['gender'].astype('category')
df['joined'] = pd.to_datetime(df['joined'])
정리
- 수치형(int/float) → 연산, 통계에 사용
- 문자열(object/string) → 텍스트 데이터
- 범주형(category) → 라벨/집단 구분, 메모리 효율
- 불리언(bool) → 조건 필터링
- 날짜(datetime, timedelta) → 시계열 처리
✅ 데이터 불러오기 및 저장
🔰 CSV 파일 읽기/쓰기
pd.read_csv('파일경로')
- : 파일 경로 또는 URL로부터 CSV 파일을 읽어 DataFrame 을 얻음
- 구분자가 콤마가 아닌 경우 sep 인자를 지정할 수 있고, 헤더가 없는 파일은 header=None으로 읽은 뒤 컬럼 이름을 지정
- 한글이 포함된 CSV의 경우 인코딩 문제로 읽지 못할 때 pd.read_csv('file.csv', encoding='utf-8') 혹은 필요한 인코딩(e.g. 'cp949')을 지정
- parse_dates=['Order Date']처럼 날짜 컬럼을 바로 날짜 타입으로 읽도록 지정할 수 있음
orders = pd.read_csv("superstore_orders.csv")
print(orders.head(5))
*>>> 출력
Row ID Order ID Order Date Ship Date Ship Mode Customer ID ....
0 1 CA-2017-152156 08/11/2017 11/11/2017 Second Class CG-12520
1 2 CA-2017-152156 08/11/2017 11/11/2017 Second Class CG-12520
2 3 CA-2017-138688 12/06/2017 16/06/2017 Second Class DV-13045
3 4 US-2016-108966 11/10/2016 18/10/2016 Standard Class SO-20335
4 5 US-2016-108966 11/10/2016 18/10/2016 Standard Class SO-20335*
DataFrame.to_csv('파일경로', index=False)
- : 편집 또는 분석한 데이터프레임을 CSV로 저장
- Index=False를 지정하면 행 인덱스 저장하지 않고 오직 데이터만 저장 (행 번호 의미 없는 경우 다수)
orders.to_csv('processed_orders.csv', index=False)
🔰 Excel 파일 읽기/쓰기
- pd.read_excel('파일경로', sheet_name=0)
- : 엑셀 파일 읽기
- sheet_name 파라미터로 시트 이름이나 번호를 지정하여 특정 시트만 불러옴 (기본 0 첫번째)
- DataFrame.to_excel('파일경로', index=False)
- : 데이터프레임을 엑셀 파일로 저장
- DataFrame.to_excel(writer, sheet_name='Sheet1')
- : 여러 데이터프레임을 다른 시트에 쓸 수 있음
import pandas as pd
df_sample = pd.DataFrame({"X": [1, 2], "Y": [3, 4]}) # 샘플 데이터프레임 생성
df_sample.to_excel("sample.xlsx", index=False) # Excel로 저장
df_new = pd.read_excel("sample.xlsx") # Excel로부터 읽기
print(df_new)
*>>> 출력
X Y
0 1 3
1 2 4*
# orders라는 df를 상위 3줄만 가져와서 orders_sample.xlsx 로 저장하겠다
orders.head(3).to_excel("orders_sample.xlsx", index=False)
orderxl = pd.read_excel("orders_sample.xlsx")
print(orderxl)
*>>> 출력
Row ID Order ID Order Date Ship Date Ship Mode Customer ID \\
0 1 CA-2017-152156 08/11/2017 11/11/2017 Second Class CG-12520
1 2 CA-2017-152156 08/11/2017 11/11/2017 Second Class CG-12520
2 3 CA-2017-138688 12/06/2017 16/06/2017 Second Class DV-13045*
🔰 JSON 파일 읽기/쓰기
- pd.read_json('파일경로')
- : JSON 구조가 표 형태로 바로 떨어지는 경우에만 데이터프레임으로 만들 수 있음
- DataFrame.to_json('파일경로', orient='records')
- : 데이터를 JSON 파일로 저장
- orient=’records’ ⇒ 밑의 예씨와 같이 리스트 내부에 각 행이 객체(record)로 표현된 JSON 형태로 저장됨 (orient=’columns’ 로 저장하면 조금 다른 포맷이 되므로 일반적으로 ’records’)
# people.JSON 파일 [ {"name": "Alice", "age": 25, "city": "NY"}, {"name": "Bob", "age": 30, "city": "LA"} ]people = pd.read_json('people.json') print(people) *>>> 출력 name age city 0 Alice 25 NY 1 Bob 30 LA*
✅ 데이터 인덱싱 / 슬라이싱
🔰 .loc
.loc[행인덱스, 열이름]
라벨 기반 인덱싱
- 인덱스의 이름이나 컬럼 이름을 사용해 원하는 부분의 데이터를 가져옴
- 양끝을 모두 포함 ⭕ (숫자 라벨이어도 .loc[1:3]이라면 1,2,3 인덱스를 모두 포함)
예시 ) 인덱스 라벨이 문자형인 데이터프레임 생성. 인덱스 라벨은 a, b, c, d,e
df = pd.DataFrame({'val': [10, 20, 30, 40, 50]}, index=['a','b','c','d','e'])
print(df)
*>>> 출력
val
a 10
b 20
c 30
d 40
e 50*
print(df.loc["a" : "c"])
>>> 출력
val
a 10
b 20
c 30
- df.loc['b'] : 인덱스 'b'인 한 행을 선택하면 그 행이 Series로 반환
- df.loc[:, 'val'] : : 을 사용해 모든 행에 대해 특정 열만 선택
- df.loc[df['val'] > 20] : boolean 배열(조건) 사용 가능
print(df.loc['b', 'val']) # 출력 : 20
print(df.loc[['a','c'], 'val']) # 출력 : a 10 c 30
print(df.loc[:, 'val'])
print(df.loc[df['val'] > 20])
*>>> 출력
↓ print(df.loc[:, 'val'])
a 10
b 20
c 30
d 40
e 50
↓ print(df.loc[df['val'] > 20])
val
c 30
d 40
e 50*
🔰 .iloc
.iloc[행번호, 열번호]
정수 기반 인덱싱
- 0부터 시작하는 정수 인덱스 위치로 데이터를 선택
- 파이썬의 리스트 슬라이싱과 유사하게 동작하며, 끝 범위를 포함 ❌
print(df.iloc[0:2])
*>>> 출력
val
a 10
b 20*
🔰
- 컬럼 선택
- 특정 열 선택 : df['컬럼명']
- ex. orders['Profit']은 orders 데이터프레임에서 'Profit' 컬럼만 추출하여 Series로 반환
- 여러 열 선택 : df[['컬럼1','컬럼2']] 같이 리스트로 컬럼명 전달
- ex. df.loc[:, ['컬럼1','컬럼2']]와 같은 표현은 모든 행에 대해 두 컬럼을 선택
- 행 슬라이싱
- 범위로 슬라이싱 할 때 .loc과 .iloc를 모두 사용 가능
- 보통은 행은 .iloc로 번호 기반 슬라이싱을, 열은 이름으로 지정하는 혼합 형태를 씀
- ex. df.iloc[:5, :3]는 첫 5행, 첫 3열 데이터를 선택
- 특정 컬럼의 값 분포
- value_counts()
- ex. df[특정 컬럼].value_counts()
✅ 조건 필터링
단일 조건으로 필터링
- 판다스에서는 조건식을 활용한 불리언 인덱싱(Boolean Indexing)으로 필터링을 간단하게 구현
- DataFrame이나 Series에 조건식을 적용하면 True/False 값으로 이루어진 동일한 크기의 불리언 Series가 만들어짐. 이 값을 인덱싱에 사용하면 True에 해당하는 행만 선택됨
- 조건식을 대괄호 [] 안에 넣어 인덱싱함으로써 매우 간단히 필터링을 수행
- 예시 ) seaborn 라이브러리의 tips 데이터셋 사용하여 진행
import seaborn as sns
tips = sns.load_dataset("tips")
print(tips.head(6))
>>> 출력
total_bill tip sex smoker day time size
0 16.99 1.01 Female No Sun Dinner 2
1 10.34 1.66 Male No Sun Dinner 3
2 21.01 3.50 Male No Sun Dinner 3
3 23.68 3.31 Male No Sun Dinner 2
4 24.59 3.61 Female No Sun Dinner 4
5 25.29 4.71 Male No Sun Dinner 4
- tip 금액이 5 초과인 경우를 필터링 ⇒ tips['tip'] > 5
high_tips = tips[tips["tip"] > 5]
print(high_tips[["total_bill", "tip", "day"]].head())
>>> 출력
total_bill tip day
23 39.42 7.58 Sat
44 30.40 5.60 Sun
47 32.40 6.00 Sun
52 34.81 5.20 Sun
59 48.27 6.73 Sat
여러 조건 결합
- 조건을 여러 개 결합할 때는 논리 연산자 &(AND), |(OR), ~(NOT) 등을 사용
- 이 때 반드시 각 조건을 괄호로 묶고, 파이썬의 and/or 대신 판다스용 & / | 를 사용
- 예시 ) 요일이 Sun 이면서 팁이 5 초과인 경우
cond = (tips["day"] == "Sun") & (tips["tip"] > 5)
suntip = tips[cond]
print(suntip[["total_bill", "tip", "day"]].head())
*>>> 출력
total_bill tip day
44 30.40 5.60 Sun
47 32.40 6.00 Sun
52 34.81 5.20 Sun
116 29.93 5.07 Sun
155 29.85 5.14 Sun*
.loc 를 사용한 조건 필터링
- df.loc[ 조건식 ]
- tips.loc[tips['time']=='Dinner', :] : Dinner인 모든 행을 선택
⇒ .loc 안에서 콤마 좌측에 조건식을 넣고, 콤마 우측에 :를 넣어 모든 컬럼을 선택. 이는 tips[tips['time']=='Dinner']와 동일한 결과
필터링된 데이터 활용
- 필터링 결과도 데이터프레임이므로, 이어서 다른 연산을 할 수 있음
- 예시 ) 요일에 팁을 $5 넘게 준 그룹들의 평균 총 지불 금액은 얼마?
- mean_total = suntip["total_bill"].mean() print(f"일요일에 $5 초과 팁을 준 그룹들의 총 지불액 평균 : ${mean_total:.2f}") *>>> 출력 일요일에 $5 초과 팁을 준 그룹들의 총 지불액 평균 : $26.39*
✅ 데이터 정렬 / 정제
🔰 데이터 정렬
데이터 정렬 (sorting) : 데이터를 값의 크기나 알파벳순으로 순서대로 배치
sort_values() - 값을 기준으로 정렬
- 기본은 오름차순(ascending=True)이며, 내림차순은 ascending=False
- by 파라미터에 컬럼명을 지정하여 정렬 기준 컬럼을 설정 (Series에는 by 없이 자기 자신의 값 기준으로 정렬)
- by 파라미터를 사용해서 여러 컬럼을 기준으로 정렬도 가능하고 ascending=[False, True] 처럼 각기 다른 정렬을 줄 수 있음
- 예시 ) tips 에서 팁 금액이 큰 순서대로 상위 몇 개 행을 보고 싶다
sorted_tips = tips.sort_values(by="tip", ascending=False)
print(sorted_tips[["total_bill", "tip", "size"]].head(3))
*>>>
total_bill tip size
170 50.81 10.00 3
212 48.33 9.00 4
23 39.42 7.58 4*
sort_index() - 인덱스를 기준으로 정렬
- 행 인덱스 라벨을 기준으로 정렬
- 기본 오름차순이며, ascending=False로 내림차순 정렬
- 예시 ) 인덱스 내림차순
reverse_idx = tips.sort_index(ascending=False)
print(reverse_idx.head(4))
*>>> 출력
total_bill tip sex smoker day time size
243 18.78 3.00 Female No Thur Dinner 2
242 17.82 1.75 Male No Sat Dinner 2
241 22.67 2.00 Male Yes Sat Dinner 2
240 27.18 2.00 Female Yes Sat Dinner 2*
🔰 데이터 정제
데이터 정제(cleaning) : 데이터셋에서 잘못되거나 불필요한 데이터를 수정 또는 제거하는 모든 작업
컬럼명 정리
- DataFrame.rename()
- orders.columns = [col.lower() for col in orders.columns] 식으로 컬럼명을 전부 소문자로 바꾸는 식의 처리도 할 수 있음
# Order Date 컬럼 -> Order_Date 로 변경
orders = orders.rename(columns={'Order Date': 'Order_Date'})
print(orders.head(3))
>>>
Row ID Order ID Order_Date Ship Date Ship Mode Customer ID \
0 1 CA-2017-152156 08/11/2017 11/11/2017 Second Class CG-12520
1 2 CA-2017-152156 08/11/2017 11/11/2017 Second Class CG-12520
2 3 CA-2017-138688 12/06/2017 16/06/2017 Second Class DV-13045
불필요한 컬럼 제거
- DataFrame.drop()
- 컬럼을 제거할 때는 axis=1 또는 columns= 파라미터를 사용
# 'Row ID' 컬럼은 행별 식별자. 단순 행 번호이므로 불필요하여 제거
orders = orders.drop(columns=['Row ID'])
데이터 값 수정 / 제거
- Series.str.strip() : 불필요한 좌우 공백 제거
- Series.str.lower() or Series.str.upper() : 대소문자 섞인 값을 통일
import pandas as pd
cities = pd.Series([' new york', 'Los Angeles ', 'Chicago', ' new york'])
cleaned1 = cities.str.strip()
cleaned2 = cities.str.strip().str.title()
print(cleaned1)
print(cleaned2)
>>>
*↓* print(cleaned1)
0 new york
1 Los Angeles
2 Chicago
3 new york
dtype: object
*↓* print(cleaned2)
['New York' 'Los Angeles' 'Chicago']
✅ 결측치 처리
결측치(Missing Data)❓
데이터셋에서 값이 채워져 있지 않은 항목. 보통 빈 값, NULL, NaN(Not a Number) 등의 형태로 표현
예시) 간단한 데이터프레임 생성
import numpy as np
df_miss = pd.DataFrame({
'name': ['Alice', 'Bob', 'Charlie'],
'age': [25, np.nan, 30],
'city': ['New York', 'Los Angeles', np.nan]
})
print(df_miss)
*>>> 출력
name age city
0 Alice 25.0 New York
1 Bob NaN Los Angeles
2 Charlie 30.0 NaN*
🔰 결측치 확인
isnull() / notnull()
- Series나 DataFrame의 각 원소가 결측치인지 아닌지를 True/False로 나타내는 동일한 모양의 객체를 반환
- df.isnull()은 결측이면 True, 값이 있으면 False
- df.notnull()은 반대로 값이 있으면 True
df.isnull().sum()
- 각 컬럼별 결측치 개수 확인 (True를 1로 간주하여 합계)
- 또는 df.info()에서도 Non-Null Count를 보여주므로 간접적으로 알 수 있음
print(df_miss.isnull().sum())
>>>
name 0
age 1
city 1
dtype: int64
# df_miss 데이터프레임에서 Bob의 나이(age)가 NaN으로 결측이며,
# Charlie의 도시(city)가 NaN으로 결측
🔰 결측치 삭제
dropna
- 결측치가 있는 행(row) 또는 열(column)을 제거
- 하나라도 결측치가 있는 행을 모두 제거
- 결측치가 데이터의 일부 열에만 집중되어 있다면, 특정 열만 제거
- df.dropna(subset=['컬럼명1', '컬럼명2'], inplace=False
- thresh(임계치) 옵션으로 일정 개수 이상의 값이 있는 행만 남기는 등의 조정
print(df_miss.dropna())
>>>
name age city
0 Alice 25.0 New York
위 결과를 보면 결측치가 있던 행(인덱스 1과 2)이 제거되고, Alice의 데이터만 남음
이렇게 하면 간단히 결측치를 없앨 수 있지만, 데이터 손실이 크기 때문에 상황에 따라 적절치 않을 수 있음
df.dropna(axis=1)
- 특정 축 방향으로 삭제 ⇒ 결측치 있는 컬럼을 제거
print(df_miss.dropna(axis=1))
*>>> 출력
name
0 Alice
1 Bob
2 Charlie*
결측치 있던 컬럼인 age와 city 컬럼이 날아가고 name만 남음
이는 일반적으로 정보 손실이 크므로 잘 안 씀
대신 행 삭제는 흔히 사용되지만, 가능한 경우에만 사용
🔰 결측치 대체
fillna
- 완전히 지워버리기 어려운 경우, 결측값을 다른 값으로 대체(impute)
- 고정값 대체 : df.fillna(0)처럼 하나의 값(예: 0)으로 모든 결측치를 채움. 또는 컬럼별로 다른 값으로 채우고 싶다면 딕셔너리를 인자로 df.fillna({'age': df['age'].mean(), 'city': 'Unknown'})
- 통계값으로 대체 : 보통 수치형 데이터는 평균이나 중앙값으로 결측치를 채우고, 범주형 데이터는 최빈값 또는 'Unknown'같은 표시로 채우기도 함
- inplace=True : 원 데이터프레임을 직접 수정. inplace를 사용하지 않으면 df_filled = df_miss.fillna({...}) 형태로 새로운 객체를 받아야 함. 코드 스타일에 따라 둘 중 편한 것 쓰기
df_filled = df_miss.copy()
df_filled["age"].fillna(df_filled["age"].mean(), inplace=True)
df_filled["city"].fillna("Unknown", inplace=True)
print(df_filled)
*>>> 출력
name age city
0 Alice 25.0 New York
1 Bob 27.5 Los Angeles
2 Charlie 30.0 Unknown*
Bob의 age가 27.5로 채워짐 (25과 30의 평균인 27.5를 대입).
Charlie의 city가 'Unknown' 문자열로 채워짐
이렇게 하면 더 이상 결측치가 없으므로 이후 분석에서 오류가 날 가능성이 줄어든다
결측치 처리 전략
어떤 방법이 좋은지는 데이터의 특성과 분석 목적에 따라 다름.
중요한 컬럼에 결측치가 많다면 행을 버리는 것은 위험하고, 그렇다고 함부로 채우는 것도 왜곡을 줄 수 있음.
따라서,
- 가능한 한 데이터 수집 단계에서 결측을 줄이도록 하고,
- 불가피한 결측에 대해서는 삭제해도 되는지, 대체해야 하는지 판단하라
- 대체한다면 그 근거(평균? 이전값? 도메인 지식 기반?)를 생각해야 하며, 결측치를 별도의 범주로 취급하는 방법도 있다.
✅ 중복 제거
중복 데이터(duplicates)❓
데이터셋에서 완전히 동일한 행이 반복되는 경우나, 특정 기준으로 볼 때 중복인 데이터 포인트
중복 데이터는 분석 결과를 왜곡시킬 수 있으므로, 적절히 제거하거나 처리
duplicated()
- 각 행이 이전에 나타난 적이 있는지 여부를 True/False로 표시한 불리언 Series를 반환
- 기본으로 첫 번째 등장만 False (중복 아님)이고, 그 이후 중복들은 True로 표시. (duplicated(keep='first')가 기본 동작.
- 반대로 'last'로 하면 마지막만 남기고 처음들을 True로 표시, False로 하면 모든 중복을 True 표시).
df_dup = pd.DataFrame({'A': [1, 1, 2, 3], 'B': [5, 5, 6, 7]})
print(df_dup)
print("--------Duplicates :\\n", df_dup.duplicated())
>>> 출력
*A B
0 1 5
1 1 5
2 2 6
3 3 7
--------Duplicates :
0 False
1 True
2 False
3 False*
drop_duplicates()
- 중복 행을 제거
- 기본적으로 처음 등장한 행은 남기고 이후 중복은 제거하며 (keep='first'), 인덱스는 기존 순서를 유지합니다 (인덱스가 재정렬되진 않음).
- 원본을 변경하려면 inplace=True를 쓰거나, 결과를 새로운 데이터프레임으로 받아야 함
print(df_dup.drop_duplicates())
*>>> 출력
A B
0 1 5
2 2 6
3 3 7*
특정 열 기준 중복 제거
- 가령 여러 열 중 특정 열만 보고 중복 판단을 할 수도 있음
- df.drop_duplicates(subset=['컬럼명'])으로 지정하면 해당 컬럼값이 같은 행들 중 중복을 제거
- 예를 들어 subset=['A']로 하면 A열 값이 같은 행은 하나만 남기고 제거
keep 옵션
- keep='first'|'last'|False 옵션으로 중복 데이터 중 어느 것을 남길지 결정
- 기본 'first'는 처음 발견을 남김, 'last'는 마지막 발견을 남김, False는 중복된 것 전부 제거 (이 경우 중복 그룹의 데이터가 아예 없어짐)
🔰 과제
실습
'Sparta > Theory' 카테고리의 다른 글
| [250830] pandas (1) | 2025.09.01 |
|---|---|
| [250829] 스파르타코딩 본캠프 19일차 (1) - pandas 02 (0) | 2025.08.29 |
| [250825] 스파르타코딩 본캠프 15일차 (1) (1) | 2025.08.25 |
| [250822] 스파르타코딩 본캠프 14일차 (1) - Python 04 - dict, def (3) | 2025.08.22 |
| [250821] 스파르타코딩 본캠프 13일차 (1) - Python 03 - list (2) | 2025.08.21 |