Python

판다스로 데이터 전처리할 때 매번 헷갈리는 코드 정리 (feat. None, isnull, contains)

2023. 11. 10. by 박하람

오랜만에 파이썬으로 데이터를 전처리하다보면, 파이썬 코드가 가물가물하다. 그 중 매번 헷갈리는 코드가 있다.

  • (1) read_csv 로 읽어올 때 None 값으로 설정하기
  • (2) date 형식으로 데이터 변경하기
  • (3) 특정 데이터프레임의 값이 비어있거나 비어있지 않은 행만 가져오기
  • (4) 특정 문자열 또는 데이터 프레임에 특정한 값이 포함되어 있는지 확인하기

매번 코드 검색하기 귀찮아서 한 번에 정리해본다!

데이터 불러올 때 None 설정

파이썬에서 결측값은 None으로 처리된다. 그러나, 종종 엑셀이나 csv 파일을 열 때, 결측값이 인식되지 않고 '' 또는 np.nan 등으로 처리되는 경우가 있다. 이럴 때 isnull()이란 구문이 먹히지 않아 데이터 전처리가 종종 어렵다. 모든 결측값이 None으로 처리될 수 있도록 작업하는 코드는 다음과 같다.

df = pd.read_excel(
    "data/sample.xlsx",
    keep_default_na=False,
    dtype=str  # 데이터타입 지정하기
)

df = df.replace({'': None}) # ''인 값은 None으로 지정
print("총 행수는 ", df.shape[0], " 입니다.", "\n")

첫번째 줄만 불러와도 결측값은 isnull()로 판별이 되지 않는다. 모든 컬럼의 데이터타입(dtype)을 string으로 줬기 때문에, 빈 값은 ''로 인식된다. 이 때 '' 값을 None으로 대체하는 구문 한 줄만 쓰면 isnull()로 결측값을 판별할 수 있다.

그러나, 모든 값이 None으로 처리되면 apply lambda를 사용해 문자열 처리를 하기 쉽지 않다. 예를 들어, 다음의 테이블이 있다고 생각해보자.

시도명시군구명읍면동명전체 행정구역명
서울특별시NoneNone서울특별시
서울특별시서대문구None서울특별시 서대문구
서울특별시서대문구신촌동서울특별시 서대문구 신촌동

위의 테이블을 기반으로 전체 행정구역명 컬럼을 만든다면, apply lambda를 사용해 전체 행정구역명을 만들기 어렵다. None은 문자열이 아니기 때문에 단순히 문자열 합을 할 수 없다. 이 경우는 데이터를 읽어올 때부터 None값이 ''로 읽어와 처리하는 게 편하다.

df = pd.read_excel(
    "data/sample.xlsx",
    keep_default_na=False,
    dtype=str  # 데이터타입 지정하기
)

df['전체 행정구역명'] = df.apply(lambda row: row['시도명'] + ' ' + row['시군구명'] + ' ' + row['읍면동명'], axis=1)

date 형식으로 데이터 변경하기

간단한 코드인데 은근히 오랜만에 판다스를 만지다보면 잘 기억이 안난다. 생성일자 값이 20231011로 되어 있을 때, 2023-10-11로 바꾸는 방법은 다음과 같다.

df['생성일자'] = pd.to_datetime(df['생성일자'], format='%Y%m%d')
df['생성일자'] = df['생성일자'].apply(lambda x: x.date())

첫번째 줄만 사용하면, 시분초 값도 함께 나온다. 두번째 줄의 코드를 사용하면 date 값만 가져올 수 있다.

특정 데이터프레임의 값이 비어있거나 비어있지 않은 행만 가져오기

df[df['컬럼1'].isnull() & df['컬럼2'].notnull()]

컬럼1의 값이 None이고, 컬럼2의 값이 None이 아닌 행을 가져오고 싶다면 위의 코드를 작성하면 된다. 이 코드는 솜솜의 블로그를 참고했다.

Tags:
#python
#pandas
#None