PySpark 5 - 날짜·배열·null처리·Join

no-glass-otacku·2026년 6월 19일

MS data school

목록 보기
23/25
노트북핵심 주제
9 Datetimes타임스탬프 변환, 날짜 포맷, 날짜 추출·조작
10 Complex Types문자열 함수, 배열 컬렉션 함수, union
11 Additional Functionscol/lit, Null 처리 (na), DataFrame join

1. 날짜/시간 함수 (9 Datetimes)

1-1. 타임스탬프로 변환 — cast()

비유: cast는 "형변환 캐스팅" — 배우(데이터)를 다른 역할(타입)로 바꾸는 것

원시 데이터의 타임스탬프는 보통 마이크로초(μs) 단위 Long 숫자로 저장됨.
초 단위로 바꾸려면 1e6(= 1,000,000)으로 나눈 뒤 cast.

# 방법 A: 문자열로 타입 지정
timestamp_df = df.withColumn("timestamp", (col("timestamp") / 1e6).cast("timestamp"))

# 방법 B: TimestampType 객체로 지정 (동일한 결과)
from pyspark.sql.types import TimestampType
timestamp_df = df.withColumn("timestamp", (col("timestamp") / 1e6).cast(TimestampType()))
인자설명
"timestamp"변환할 타입 (문자열)
TimestampType()변환할 타입 (타입 객체)

1-2. 날짜 포맷 지정 — date_format()

from pyspark.sql.functions import date_format

df.withColumn("date string", date_format("timestamp", "MMMM dd, yyyy"))
  .withColumn("time string", date_format("timestamp", "HH:mm:ss.SSSSSS"))
인자설명
1번째변환할 컬럼 (컬럼명 문자열 또는 col 객체)
2번째날짜 패턴 문자열

주요 날짜 패턴 문자

패턴의미예시
yyyy4자리 연도2024
MM2자리 월07
MMMM월 전체 이름July
dd2자리 일28
HH24시간 시14
mm30
ss05
SSSSSS마이크로초123456

1-3. 날짜/시간 속성 추출

타임스탬프에서 연/월/일/분/초를 숫자 컬럼으로 뽑아냄

from pyspark.sql.functions import year, month, dayofweek, minute, second

df.withColumn("year",      year(col("timestamp")))
  .withColumn("month",     month(col("timestamp")))
  .withColumn("dayofweek", dayofweek(col("timestamp")))  # 1=일요일, 7=토요일
  .withColumn("minute",    minute(col("timestamp")))
  .withColumn("second",    second(col("timestamp")))

모두 동일한 형태: 함수명(컬럼) → 정수 반환


1-4. 날짜 타입으로 변환 — to_date()

타임스탬프(날짜+시간) → 날짜만 남김 (시간 정보 제거)

from pyspark.sql.functions import to_date

date_df = timestamp_df.withColumn("date", to_date(col("timestamp")))
# 결과: "2023-07-15 14:30:00" → "2023-07-15"

1-5. 날짜 더하기 — date_add()

from pyspark.sql.functions import date_add

df.withColumn("plus_two_days", date_add(col("timestamp"), 2))
인자설명
1번째기준 날짜 컬럼
2번째더할 일수 (정수)

1-6. 기타 유용한 날짜 함수 (참고용)

함수설명
current_timestamp()현재 시각 반환
add_months(col, n)n달 후 날짜
from_unixtime(col)Unix 초 → 날짜 문자열
unix_timestamp(col)날짜 문자열 → Unix 초

2. 복합 타입 함수 (10 Complex Types)

2-1. 문자열 함수

from pyspark.sql.functions import split, lower, regexp_replace  # 필요한 것만 import
함수설명예시
split(col, 패턴, limit)패턴 기준으로 문자열 분리 → 배열 반환split(col("email"), "@", 0)
lower(col)소문자 변환lower(col("name"))
ltrim(col)왼쪽 공백 제거ltrim(col("text"))
regexp_replace(col, 패턴, 치환)정규식 패턴 치환regexp_replace(col("s"), "[0-9]", "")
regexp_extract(col, 패턴, idx)정규식으로 일부 추출
translate(col, src, rep)문자 단위 치환

split() 예시

# email에서 @ 기준으로 분리
df.select(split(df.email, '@', 0).alias('email_handle'))
# 결과: ["user", "gmail.com"] 형태의 배열 컬럼
split 인자설명
1번째분리할 컬럼
2번째구분 패턴 (정규식)
3번째최대 분리 수 (0 = 제한 없음)

2-2. 컬렉션 함수 (배열 조작)

비유: 배열이 담긴 컬럼을 다루는 함수들. 마치 리스트를 다루는 파이썬 메서드처럼.

함수설명예시
explode(col)배열의 각 요소를 별도 행으로 분리아래 참고
array_contains(col, 값)배열에 값이 있으면 Truearray_contains(col("details"), "Mattress")
element_at(col, 인덱스)배열의 n번째 요소 반환 (1부터 시작)element_at(col("details"), 2)

explode() 핵심

# items 컬럼이 배열이면, 각 원소가 별도 행으로 "터져 나옴"
sales_exploded_df = df.withColumn("items", explode("items"))

비유: 달걀 한 판(배열)을 하나씩 꺼내서 각각 새 줄에 올려놓는 것

실전 패턴 — explode → select → split

details_df = (df
              .withColumn("items", explode("items"))          # 배열 → 행 분리
              .select("email", "items.item_name")             # 필요 컬럼만
              .withColumn("details", split(col("item_name"), " "))  # 문자열 → 배열
             )

2-3. 집계 함수 (배열 생성)

함수설명
collect_set(col)그룹 내 고유값만 모아서 배열로 반환 (중복 제거)
collect_list(col)그룹 내 모든 값을 배열로 반환 (중복 포함)
# 이메일별로 주문한 매트리스 크기 종류 수집
size_df = mattress_df.groupBy("email").agg(collect_set("size").alias("size options"))

2-4. DataFrame 합치기 — union vs unionByName

비유:

  • union = 위치 기준 합치기 (컬럼 순서가 같아야 안전)
  • unionByName = 이름 기준 합치기 (컬럼 순서 달라도 OK)
# union: 컬럼 순서가 완전히 같을 때
df1.union(df2)

# unionByName: 컬럼명이 같으면 순서 달라도 됨 (더 안전)
df1.unionByName(df2)

⚠️ 둘 다 중복 행을 제거하지 않음 (SQL의 UNION ALL과 같음)


3. 추가 함수 (11 Additional Functions)

3-1. col() — 컬럼 객체 참조

from pyspark.sql.functions import col

# 문자열 컬럼명 대신 col 객체를 쓰면 메서드 체이닝 가능
df.filter(col("email").endswith("gmail.com"))

왜 쓰나?: "email" 문자열은 그냥 이름이지만, col("email")은 컬럼 객체라서 .endswith(), .isNull() 같은 메서드를 붙일 수 있음


3-2. lit() — 고정값으로 컬럼 만들기

from pyspark.sql.functions import lit

# 모든 행에 True 값을 가진 "gmail user" 컬럼 추가
df.select("email", lit(True).alias("gmail user"))
lit 인자설명
아무 Python 값문자열, 숫자, 불리언 모두 가능

비유: 모든 행에 도장 찍기. "이 데이터는 전부 gmail 유저다" 같은 플래그 컬럼 만들 때 유용


3-3. Null 처리 — df.na

접근 방법: df.na.함수명() 형태로 사용

메서드설명
df.na.drop()null 있는 행 전체 삭제
df.na.fill(값)null을 지정값으로 채움
df.na.replace(찾을값, 바꿀값)특정 값을 다른 값으로 교체
# null 있는 행 제거
df.na.drop()

# null을 "NO COUPON"으로 채우기
df.na.fill("NO COUPON")

# 행 수 비교로 null 존재 확인
print(df.count())          # 전체
print(df.na.drop().count()) # null 제거 후 → 숫자 다르면 null 있음

⚠️ 주의: 배열 컬럼(items 같은) 안에 null이 있으면 na.drop()으로 안 잡힘.
explode() 먼저 해서 펼친 뒤 확인해야 함.


3-4. DataFrame 조인 — join()

df1.join(other=df2, on=조인조건, how=조인방식)
인자설명
other조인할 두 번째 DataFrame
on조인 기준 컬럼 (문자열, 리스트, 또는 조건식)
how조인 방식 (아래 표 참고)

조인 방식 (how)

설명
"inner"양쪽 모두 있는 행만 (기본값)
"left" / "left_outer"왼쪽 기준, 오른쪽에 없으면 null
"right" / "right_outer"오른쪽 기준
"outer" / "full"양쪽 모두 포함

예시 패턴

# 같은 이름의 컬럼으로 inner join
joined_df = df1.join(other=df2, on="email", how="inner")

# 여러 컬럼으로 join
df1.join(df2, ["name", "age"])

# 컬럼명이 다를 때
df1.join(df2, df1["customer_name"] == df2["account_name"], "left_outer")

4. 전체 함수 빠른 참조표

날짜/시간

함수인자반환
.cast("timestamp")타입명 문자열변환된 컬럼
date_format(col, 패턴)컬럼, 패턴 문자열문자열 컬럼
to_date(col)컬럼DateType 컬럼
date_add(col, n)컬럼, 정수DateType 컬럼
year/month/dayofweek/minute/second(col)컬럼정수 컬럼

문자열

함수인자반환
split(col, 패턴, limit)컬럼, 패턴, 최대분리수ArrayType 컬럼
lower(col)컬럼StringType
regexp_replace(col, 패턴, 치환)컬럼, 정규식, 치환문자StringType

컬렉션/배열

함수인자반환
explode(col)배열 컬럼행 분리된 DataFrame
array_contains(col, 값)배열 컬럼, 찾을 값BooleanType
element_at(col, n)배열 컬럼, 인덱스(1부터)원소 타입
collect_set(col)컬럼ArrayType (중복 제거)
collect_list(col)컬럼ArrayType (중복 포함)

기타

함수/메서드인자용도
col("컬럼명")문자열컬럼 객체 반환
lit(값)Python 값고정값 컬럼 생성
df.na.drop()없음null 행 제거
df.na.fill(값)채울 값null 채우기
df1.join(df2, on, how)DF, 조건, 방식두 DF 결합
df1.union(df2)DF위치 기준 합치기
df1.unionByName(df2)DF이름 기준 합치기
profile
이제 개발해야지...

0개의 댓글