기술 노트/Apache Spark

Apache Spark 실무 활용 가이드: 데이터 처리와 최적화

anothel 2024. 3. 31. 22:39

서론: Spark와 실무 데이터 분석의 필요성

Spark는 대규모 데이터를 빠르게 처리하고 머신러닝 파이프라인을 구축할 수 있는 강력한 분산 컴퓨팅 프레임워크다. Pandas나 SQL 기반 데이터베이스도 데이터 분석에 널리 쓰이지만, 대규모 데이터에서는 메모리 및 성능 문제가 발생하기 쉽다. Spark는 클러스터를 통한 분산 처리를 지원하여 대규모 데이터에서도 성능 저하 없이 빠르게 처리할 수 있어 실무에서 폭넓게 사용되고 있다.

이번 글에서는 Spark의 주요 기능과 실무에서의 활용 팁을 정리하여 실무적 인사이트를 제공하고자 한다.


1. Spark와 Pandas의 데이터 구조 비교

Spark와 Pandas의 DataFrame은 데이터 분석에 주로 사용되지만, 데이터 처리 방식에서 큰 차이가 있다. Pandas는 단일 컴퓨터 메모리 내에서 데이터를 처리하는 반면, Spark는 데이터를 분산 처리해 수십억 개의 행 데이터를 다룰 수 있다.

이 섹션에서는 Pandas와 Spark의 주요 메서드 (head(), show(), printSchema(), describe(), shape)를 비교하고, 각 기능을 코드와 함께 살펴본다.

head()와 show() 비교

Pandas의 head()는 기본적으로 상위 5개 데이터를 반환하며, 행 개수를 지정할 수도 있다. Spark에서는 show()를 사용해 상위 데이터를 출력하며, 매개변수로 보여줄 행 수를 지정할 수 있다.

# Pandas에서 상위 5개 데이터 확인
import pandas as pd

pdf = pd.DataFrame({'name': ['Alice', 'Bob', 'Cathy'], 'age': [24, 27, 22]})
print(pdf.head(5))

출력 예시 (Pandas):

   name  age
0  Alice   24
1    Bob   27
2  Cathy   22

 

# Spark에서 상위 5개 데이터 확인
from pyspark.sql import SparkSession

spark = SparkSession.builder.appName("Example").getOrCreate()
spark_df = spark.createDataFrame([("Alice", 24), ("Bob", 27), ("Cathy", 22)], ["name", "age"])
spark_df.show(5)

출력 예시 (Spark):

+-----+---+
| name|age|
+-----+---+
|Alice| 24|
|  Bob| 27|
|Cathy| 22|
+-----+---+

 

printSchema()와 info() 비교

info()는 Pandas DataFrame에서 컬럼명, 데이터 타입, non-null 값 개수 등을 보여준다. Spark에서는 printSchema()를 사용하여 컬럼명과 데이터 타입을 확인할 수 있다. non-null 값의 개수를 확인하려면 추가 쿼리가 필요하다.

# Pandas에서 info() 사용
print(pdf.info())

출력 예시 (Pandas):

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3 entries, 0 to 2
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype
---  ------  --------------  -----
 0   name    3 non-null      object
 1   age     3 non-null      int64
dtypes: int64(1), object(1)
memory usage: 176.0+ bytes

 

# Spark에서 printSchema() 사용
spark_df.printSchema()

출력 예시 (Spark):

root
 |-- name: string (nullable = true)
 |-- age: long (nullable = true)

 

describe() 비교

describe()는 Pandas와 Spark 모두 기본적인 통계 정보를 제공한다. Pandas는 숫자형 데이터의 요약 통계를 제공하며, Spark는 숫자형과 문자열형 데이터 모두를 포함해 요약 통계를 보여준다.

# Pandas에서 describe() 사용
print(pdf.describe())

출력 예시 (Pandas):

           age
count   3.000000
mean   24.333333
std     2.516611
min    22.000000
25%    23.000000
50%    24.000000
75%    25.500000
max    27.000000

 

# Spark에서 describe() 사용
spark_df.describe().show()

출력 예시 (Spark):

+-------+-----+------------------+
|summary| name|               age|
+-------+-----+------------------+
|  count|    3|                 3|
|   mean| null|24.333333333333332|
| stddev| null| 2.516611478423583|
|    min|Alice|                22|
|    max|  Bob|                27|
+-------+-----+------------------+

 

shape 비교

Pandas에서 shape는 (행 수, 열 수) 형태의 튜플을 반환하여 데이터프레임의 구조를 쉽게 파악할 수 있다. Spark에서는 shape 메서드가 없기 때문에 행 수는 count()로, 컬럼 수는 len(df.columns)로 각각 확인한다.

# Pandas에서 shape 확인
print(pdf.shape)

출력 예시 (Pandas):

(3, 2)

 

# Spark에서 행 수와 컬럼 수 확인
row_count = spark_df.count()
column_count = len(spark_df.columns)
print((row_count, column_count))

출력 예시 (Spark):

(3, 2)

 

이처럼 Spark와 Pandas의 데이터 구조와 메서드를 비교해 보면, 대규모 데이터 처리 시에는 Spark가 더 효율적임을 알 수 있다.


2. Spark에서의 데이터 선택과 필터링 최적화

Spark는 대규모 데이터를 다룰 때 필요한 데이터만 선택하고 조건에 따라 필터링할 수 있는 다양한 기능을 제공하여 작업 속도와 효율성을 높인다. 여기서는 Spark에서 자주 사용하는 데이터 선택과 필터링 메서드(select(), filter(), orderBy(), sort())를 설명한다.

select()와 컬럼 지정

Spark의 select()는 SQL의 SELECT 문법과 비슷하게 특정 컬럼만 선택할 수 있어 메모리 사용량을 줄이고, 필요한 데이터만 처리할 수 있다. Pandas에서는 이와 유사한 기능을 인덱싱이나 []를 사용해 컬럼을 선택하는 방식으로 제공한다.

# Pandas에서 특정 컬럼 선택
selected_pdf = pdf[['name', 'age']]
print(selected_pdf)

출력 예시 (Pandas):

   name  age
0  Alice   24
1    Bob   27
2  Cathy   22

 

# Spark에서 특정 컬럼 선택
selected_spark_df = spark_df.select("name", "age")
selected_spark_df.show()

출력 예시 (Spark):

+-----+---+
| name|age|
+-----+---+
|Alice| 24|
|  Bob| 27|
|Cathy| 22|
+-----+---+

 

filter()와 조건 설정

Spark의 filter()와 Pandas의 조건 필터링은 데이터를 특정 조건에 맞게 필터링해 필요한 데이터만 남기는 데 유용하다. Pandas에서는 [] 내 조건을 지정해 필터링하는 방식으로, Spark에서는 SQL의 WHERE 절과 유사한 filter()를 사용해 조건을 걸 수 있다.

# Pandas에서 age가 25 이상인 행 필터링
filtered_pdf = pdf[pdf['age'] >= 25]
print(filtered_pdf)

출력 예시 (Pandas):

   name  age
1    Bob   27

 

# Spark에서 age가 25 이상인 행 필터링
filtered_spark_df = spark_df.filter(spark_df.age >= 25)
filtered_spark_df.show()

출력 예시 (Spark):

+----+---+
|name|age|
+----+---+
| Bob| 27|
+----+---+

 

orderBy()와 sort()를 사용한 정렬

Spark에서 orderBy()와 sort()는 데이터를 특정 컬럼 기준으로 정렬한다. 오름차순 및 내림차순 정렬은 ascending 매개변수를 통해 지정한다.  Pandas에서는 sort_values()를 사용해 비슷한 방식으로 정렬할 수 있다.

# Pandas에서 age 기준으로 오름차순 정렬
sorted_pdf = pdf.sort_values(by="age", ascending=True)
print(sorted_pdf)

출력 예시 (Pandas):

   name  age
2  Cathy   22
0  Alice   24
1    Bob   27

 

# Spark에서 age 기준으로 오름차순 정렬
sorted_spark_df = spark_df.orderBy("age", ascending=True)
sorted_spark_df.show()

출력 예시 (Spark):

+-----+---+
| name|age|
+-----+---+
|Cathy| 22|
|Alice| 24|
|  Bob| 27|
+-----+---+

Spark에서 여러 컬럼을 기준으로 정렬하고자 할 때는 ascending 옵션에 리스트 형태로 오름차순 또는 내림차순을 지정할 수 있다. 아래는 age 컬럼은 오름차순, name 컬럼은 내림차순으로 정렬하는 예시다.

# Spark에서 age와 name 기준으로 정렬 (age는 오름차순, name은 내림차순)
multi_sorted_spark_df = spark_df.sort(["age", "name"], ascending=[True, False])
multi_sorted_spark_df.show()

출력 예시 (Spark):

+-----+---+
| name|age|
+-----+---+
|Cathy| 22|
|Alice| 24|
|  Bob| 27|
+-----+---+

 

이처럼 Spark의 select(), filter(), orderBy(), sort() 등의 메서드를 사용하면 대규모 데이터를 효율적으로 선택하고 정렬할 수 있다.


3. Spark SQL을 활용한 데이터 처리

Spark SQL을 통해 SQL 구문을 사용하여 데이터를 조작할 수 있다. Spark SQL은 SQL에 익숙한 사용자에게 매우 유용하며, Temporary View를 통해 SQL 쿼리를 Spark DataFrame에 적용할 수 있다.

Temporary View 설정과 SQL 구문 활용

Spark SQL을 사용하려면 먼저 DataFrame을 Temporary View로 등록해야 하며, SQL 구문을 통해 데이터를 조회하거나 필터링하는 작업이 가능하다.

# DataFrame을 Temporary View로 등록
spark_df.createOrReplaceTempView("people")

# SQL 쿼리로 데이터 조회
result_df = spark.sql("SELECT * FROM people WHERE age > 25")
result_df.show()

출력 예시 (Spark):

+----+---+
|name|age|
+----+---+
| Bob| 27|
+----+---+

SQL과 DataFrame API의 차이점

Spark SQL과 DataFrame API는 같은 결과를 얻을 수 있지만, SQL 구문은 SQL에 익숙한 사용자에게 직관적일 수 있다. 반면, DataFrame API는 다양한 Spark 메서드를 활용할 수 있는 장점이 있다. 작업 목적에 따라 두 방법을 적절히 혼용할 수 있다.

 

728x90