파이썬 pandas 기초: Series·결측치·필터링 완전정리
pandas의 Series와 DataFrame 차이부터 결측치 확인·처리, 조건 필터링, loc와 iloc 사용법까지 초보자가 실무 순서대로 익힐 수 있도록 예제로 설명합니다.

pandas를 처음 배울 때는 Series는 한 개 열, DataFrame은 여러 열로 구성된 2차원 표라고 이해하면 됩니다. 실제 분석에서는 데이터를 만든 뒤 자료형과 결측치를 먼저 확인하고, 불리언 조건이나 loc로 필요한 행과 열을 선택하는 순서가 가장 안전합니다.
핵심 요약
Series는 인덱스를 가진 1차원 데이터이고,DataFrame은 여러 Series가 열로 모인 표입니다.info(),dtypes,isna().sum()으로 구조와 결측치를 먼저 점검합니다.- 결측치는 무조건 삭제하지 않고 의미와 업무 기준에 따라 유지·삭제·대체를 결정합니다.
- 필터 조건이 둘 이상이면 각 조건을 괄호로 묶고
&또는|를 사용합니다. loc는 라벨·조건 기반,iloc는 정수 위치 기반 선택에 사용합니다.
Series와 DataFrame 차이부터 이해하기
Series는 값과 인덱스가 한 쌍으로 움직이는 1차원 객체입니다. 데이터프레임에서 df["매출"]처럼 열 하나를 선택하면 보통 Series가 반환됩니다. DataFrame은 행과 열이 있는 2차원 객체이며 문자, 정수, 실수처럼 서로 다른 자료형의 열을 함께 담을 수 있습니다.
| 구분 | Series | DataFrame |
|---|---|---|
| 차원 | 1차원 | 2차원 |
| 형태 | 한 개 열과 인덱스 | 여러 열과 행 인덱스 |
| 생성 | pd.Series() |
pd.DataFrame() |
| 주요 용도 | 한 변수의 계산·변환 | 표 전체의 정리·분석 |
import pandas as pd
sales = pd.Series([120, 150, 90], name="매출")
df = pd.DataFrame({
"상품": ["A", "B", "C"],
"매출": [120, 150, 90],
"지역": ["서울", "부산", "서울"]
})
Series와 DataFrame에는 모두 인덱스가 있습니다. 기본 인덱스는 0부터 시작하지만 문자열이나 날짜를 인덱스로 지정할 수도 있습니다. 다만 초보 단계에서는 인덱스를 단순한 행 식별자로 두고, 실제 업무 키는 별도 열로 관리하는 편이 오류를 줄이기 쉽습니다.
데이터 생성 후 구조를 먼저 확인하세요
데이터를 불러오거나 직접 만들었다면 곧바로 필터링하기 전에 모양과 자료형을 점검합니다. head()는 앞부분, shape는 행·열 개수, columns는 열 이름, dtypes는 열별 자료형을 보여줍니다. info()는 결측치가 아닌 값의 개수와 자료형을 함께 확인할 때 유용합니다.
print(df.head())
print(df.shape)
print(df.columns)
print(df.dtypes)
df.info()
숫자로 계산해야 할 열이 object나 문자열로 잡혔다면 쉼표, 통화기호, 공백이 섞였는지 확인해야 합니다. 날짜도 문자열 상태로 비교하면 원하는 순서와 다르게 정렬될 수 있으므로 pd.to_datetime()으로 변환한 뒤 처리하는 것이 좋습니다.
NaN과 결측치 확인·처리 방법
pandas는 자료형에 따라 numpy.nan, NaT, pd.NA 등으로 누락된 값을 표현합니다. 이를 문자열 비교나 ==로 찾지 말고 isna() 또는 notna()를 사용해야 합니다. 열별 결측치 개수는 다음 한 줄로 확인할 수 있습니다.
print(df.isna().sum())
missing_rate = df.isna().mean().mul(100)
print(missing_rate)
| 처리 | 사용 예 | 판단 기준 |
|---|---|---|
| 유지 | 값이 아직 확인되지 않음 | 누락 자체가 정보일 때 |
| 삭제 | dropna() |
분석에 필수인 값이 없고 행을 제외해도 왜곡이 적을 때 |
| 대체 | fillna() |
업무적으로 타당한 기본값이나 통계값이 있을 때 |
# 매출이 없는 행 제거
clean = df.dropna(subset=["매출"])
# 지역 누락값을 '미확인'으로 대체
df["지역"] = df["지역"].fillna("미확인")
평균이나 0으로 일괄 대체하면 결과가 왜곡될 수 있습니다. 예를 들어 매출 0은 실제 판매가 없었다는 뜻이고, 결측치는 값이 수집되지 않았다는 뜻일 수 있습니다. 두 의미를 먼저 구분한 뒤 처리 규칙을 정해야 합니다.
조건으로 필요한 데이터만 필터링하기
열 하나를 선택할 때는 df["매출"], 여러 열은 df[["상품", "매출"]]처럼 대괄호를 한 번 더 사용합니다. 조건식은 각 행에 대해 참과 거짓을 가진 Series를 만들며, 이를 데이터프레임의 행 선택에 이용합니다.
# 매출 100 이상
high_sales = df[df["매출"] >= 100]
# 서울이면서 매출 100 이상
seoul_high = df[(df["지역"] == "서울") & (df["매출"] >= 100)]
# 여러 후보 중 하나
selected = df[df["지역"].isin(["서울", "부산"])]
파이썬의 and, or는 Series 조건을 결합하는 용도가 아닙니다. pandas에서는 &, |, 부정 조건에는 ~를 사용하고 각 비교식을 반드시 괄호로 묶습니다. 문자열 검색은 str.contains()를 쓸 수 있으며 결측치가 섞였다면 na=False를 지정하면 안전합니다.
python_rows = df[df["상품"].str.contains("Python", na=False)]
loc와 iloc는 기준이 다릅니다
loc는 행·열의 라벨과 조건을 기준으로 선택합니다. iloc는 화면에 보이는 정수 위치를 기준으로 합니다. 특히 슬라이스의 끝 처리 방식이 다르므로 혼동하기 쉽습니다.
| 방법 | 기준 | 예시 |
|---|---|---|
loc |
라벨 또는 불리언 조건 | df.loc[df["매출"] > 100, ["상품", "매출"]] |
iloc |
0부터 시작하는 정수 위치 | df.iloc[0:3, 0:2] |
loc[0:3]은 라벨 3을 포함할 수 있지만 iloc[0:3]은 위치 3을 포함하지 않습니다. 정렬이나 행 삭제 뒤에는 인덱스 라벨과 현재 위치가 달라질 수 있으므로, 코드가 무엇을 기준으로 선택하는지 명확히 해야 합니다.
초보자를 위한 실무 처리 순서
- 원본을 읽은 직후
head(),shape,info()로 구조를 확인합니다. - 열 이름의 공백과 중복, 예상하지 못한 자료형을 점검합니다.
isna().sum()으로 결측치 규모와 위치를 파악합니다.- 삭제·대체 규칙을 코드에 명시하고 원본 데이터는 보존합니다.
- 필터 조건을 하나씩 검사한 뒤 복합 조건으로 결합합니다.
- 결과 행 수와 주요 통계를 원본과 비교합니다.
- CSV나 엑셀로 저장한 뒤 다시 읽어 자료형과 값이 유지됐는지 확인합니다.
분석 결과를 서식이 포함된 엑셀 보고서로 만들어야 한다면 pandas에서 정리한 데이터와 openpyxl을 역할별로 나누어 사용할 수 있습니다.
실수 방지 체크리스트
- 열 하나와 여러 열을 선택할 때 대괄호 개수가 맞는지 확인합니다.
- 결측치를
== np.nan으로 비교하지 않았는지 확인합니다. - 0, 빈 문자열, 결측치를 같은 값으로 취급하지 않습니다.
- 복합 조건의 각 비교식을 괄호로 묶습니다.
- Series 조건에
and와or를 사용하지 않습니다. loc와iloc의 기준 및 슬라이스 끝 포함 여부를 구분합니다.- 필터 결과가 복사본인지 원본 수정인지 의도한 동작을 확인합니다.
- 원본 파일을 덮어쓰기 전에 별도 결과 파일로 검증합니다.
자주 묻는 질문
1. Series와 리스트는 무엇이 다른가요?
Series에는 값과 함께 인덱스와 자료형 정보가 있으며, 인덱스 정렬을 고려한 pandas 연산을 지원합니다. 단순 순서형 값만 필요하면 리스트가 더 가벼울 수 있습니다.
2. 열 하나를 DataFrame 형태로 유지하려면 어떻게 하나요?
df["매출"] 대신 df[["매출"]]처럼 열 이름을 리스트로 전달하면 한 열짜리 DataFrame이 반환됩니다.
3. NaN과 None은 같은 값인가요?
모두 결측치로 인식될 수 있지만 내부 표현과 자료형에 미치는 영향은 다를 수 있습니다. 확인에는 isna()를 사용하세요.
4. 결측치는 항상 삭제해야 하나요?
아닙니다. 누락 원인과 분석 목적에 따라 유지, 특정 열 기준 삭제, 업무상 타당한 값으로 대체할 수 있습니다.
5. 숫자 열이 object로 표시되는 이유는 무엇인가요?
쉼표, 통화기호, 공백, 문자 등이 섞였을 가능성이 큽니다. 원문을 정리한 뒤 pd.to_numeric()을 검토하세요.
6. 필터 결과가 비어 있을 때 무엇부터 확인하나요?
열 자료형, 앞뒤 공백, 대소문자, 결측치, 비교값의 단위를 차례로 확인하고 조건을 하나씩 실행해 보세요.
7. and 대신 &를 쓰는 이유는 무엇인가요?
&는 Series의 각 원소별 논리 연산을 수행합니다. 파이썬의 and는 Series 전체의 참·거짓을 하나로 판단하려 하므로 오류가 발생합니다.
8. loc에서 조건과 열을 동시에 선택할 수 있나요?
네. df.loc[행 조건, 열 목록] 형식으로 필요한 행과 열을 한 번에 선택할 수 있습니다.
9. 필터링 후 값을 바꿀 때 경고가 나오는 이유는 무엇인가요?
원본의 뷰인지 복사본인지 모호할 때 경고가 날 수 있습니다. 명확한 원본 수정에는 loc를 쓰고 독립 결과가 필요하면 copy()를 사용하세요.
10. pandas 버전에 따라 동작이 달라질 수 있나요?
네. 자료형과 결측치, 복사 동작 등은 버전에 따라 달라질 수 있으므로 설치 버전을 기록하고 해당 버전의 공식 문서를 확인하는 것이 좋습니다.
공식 출처
- pandas: What kind of data does pandas handle?
- pandas: Working with missing data
- pandas: How do I select a subset of a DataFrame?
공식 문서 확인일: 2026년 8월 29일