데이터로그😎
[Spark] Spark SQL에서 날짜 형식 중 년, 월, 일 따로 추출하는 법! 본문
spark3.0이 도입되면서 약간 룰이 달라졌다.
지금부터 도입 이전, 후에 어떻게 달라졌는지 알아보겠다.
Spark 3.0 이전
from pyspark.sql import SparkSession
spark = SparkSession.builder.appName('trip').getOrCreate()
filepath = '/home/ubuntu/working/spark-example/data/fhvhv_tripdata_2020-03.csv'
taxi_df = spark.read.csv(f'file:///{filepath}',
inferSchema=True, header= True)
taxi_df.show(5)
한 번 데이터 프레임의 데이터 형식을 알아볼까?
taxi_df.printSchema()
################################################
root
|-- hvfhs_license_num: string (nullable = true)
|-- dispatching_base_num: string (nullable = true)
|-- pickup_datetime: string (nullable = true)
|-- dropoff_datetime: string (nullable = true)
|-- PULocationID: integer (nullable = true)
|-- DOLocationID: integer (nullable = true)
|-- SR_Flag: integer (nullable = true)
pickup_datetime이 string인 걸 확인할 수 있다.
먼저 이 컬럼을 datetime 형식으로 변경하겠다.
데이터 형식 변경하기
df.withColumn(추가할 컬럼명, to_date(변경할 컬럼명, 변경할 형식))
from pyspark.sql.functions import to_date
taxi_df = taxi_df.withColumn('formatted_date', to_date('pickup_datetime', 'yyyy-mm-dd'))
taxi_df.printShema()
##########################################
root
|-- hvfhs_license_num: string (nullable = true)
|-- dispatching_base_num: string (nullable = true)
|-- pickup_datetime: string (nullable = true)
|-- dropoff_datetime: string (nullable = true)
|-- PULocationID: integer (nullable = true)
|-- DOLocationID: integer (nullable = true)
|-- SR_Flag: integer (nullable = true)
|-- formatted_date: date (nullable = true)
formatted_date라는 컬럼이 추가되었고 해당 컬럼의 형식이 date인게 확인된다.
년,월,일 추출하기
현재는 spark3.0이상의 버전을 이용하고 있기 때문에 그 전 버전의 policy를 적용하기 위해서는 아래의 코드를 실행할 필요가 있다.
아래 코드는 Apache Spark의 설정 중 날짜 정책을 변경하는 코드이다.
이 코드를 통해 이전 버전의 동작 방식과 호환성을 유지하고, 새로운 파서가 적용되기 이전의 방식으로 날짜 및 시간 형식을 처리한다. 즉, 이전 버전의 Spark에서 사용되던 날짜 및 시간 형식을 그대로 사용할 수 있게 해준다는 의미이다.
spark.conf.set("spark.sql.legacy.timeParserPolicy", "LEGACY")
이제 본격적으로 년,월,일을 추출해보자
MySQL에서는 date형식의 컬럼에서 YEAR, MONTH, DAY 명령어를 통해 각각 년, 월, 일을 추출할 수 있다.
taxi_df.createOrReplaceTempView('mobility_data')
query = """
SELECT YEAR(formatted_date) as year,
MONTH(formatted_date) as month,
DAY(formatted_date) as date
FROM mobility_data
"""
spark.sql(query).show()
# 결과
+----+-----+----+
|year|month|date|
+----+-----+----+
|2020| 3| 1|
|2020| 3| 1|
|2020| 3| 1|
|2020| 3| 1|
|2020| 3| 1|
|2020| 3| 1|
|2020| 3| 1|
|2020| 3| 1|
..........
Spark 3.0 이후
spark 3.0 이후 새로 적용된 날짜 형식 관련 정책에서는 sql의 YEAR, MONTH 등의 명령어를 통해 년월일을 추출할 수 없는 듯하다. 이때에는 위에서 withColumn으로 데이터 형식을 str -> date로 바꾼 것처럼 withColumn에서 년월일을 추출한다.
여기서!!! month는 꼭 MM , 대문자로 써야한다. mm으로 기재하면 minutes가 뽑히니 주의하도록!
from pyspark.sql.functions import date_format
# datetime 형식의 컬럼에서 년, 월, 일을 추출하고 각각의 새로운 컬럼을 만듭니다.
result_df = taxi_df.withColumn("year", date_format("pickup_datetime", "yyyy")) \
.withColumn("month", date_format("pickup_datetime", "MM")) \
.withColumn("day", date_format("pickup_datetime", "dd"))
result_df.show(5)
'Data Engineering' 카테고리의 다른 글
[Linux] 2. IO Redirection - output (0) | 2024.01.15 |
---|---|
[Linux] 1. 리눅스 기초 (0) | 2024.01.14 |
[Spark] Spark Machine-Learning (0) | 2023.09.15 |
[Spark] Spark SQL (0) | 2023.09.14 |
[Spark] Spark RDD (0) | 2023.09.14 |