Skip to content

Python PySpark: How to Apply Functions to Array Columns in PySpark in Python

Learn high-performance techniques for transforming array elements in PySpark using native functions like transform(), filter(), and aggregate() for efficient big data processing.

Array columns are common in big data processing-storing tags, scores, timestamps, or nested attributes within a single field. Transforming every element within these arrays efficiently requires understanding PySpark's native array functions, which execute within the JVM and avoid costly Python serialization.

This guide demonstrates high-performance techniques for manipulating array column elements at scale.

For Spark 3.0+, the transform function is the optimal choice for element-wise array operations. It applies a lambda expression to each element natively within Spark's execution engine:

from pyspark.sql import SparkSession
from pyspark.sql.functions import col, transform, upper, lower

spark = SparkSession.builder.appName("ArrayTransform").getOrCreate()

data = [
    (1, ["python", "spark", "hadoop"]),
    (2, ["machine", "learning"]),
    (3, ["big", "data", "analytics"])
]
df = spark.createDataFrame(data, ["id", "tags"])

df_upper = df.withColumn(
    "tags_upper",
    transform(col("tags"), lambda x: upper(x))
)

df_upper.show(truncate=False)

Output:

+---+---------------------------+---------------------------+
|id |tags                       |tags_upper                 |
+---+---------------------------+---------------------------+
|1  |[python, spark, hadoop]    |[PYTHON, SPARK, HADOOP]    |
|2  |[machine, learning]        |[MACHINE, LEARNING]        |
|3  |[big, data, analytics]     |[BIG, DATA, ANALYTICS]     |
+---+---------------------------+---------------------------+

Numeric Array Transformations

Apply mathematical operations to numeric arrays:

from pyspark.sql.functions import col, transform

scores_data = [
    (1, [85, 90, 78]),
    (2, [92, 88, 95]),
    (3, [70, 75, 80])
]
df_scores = spark.createDataFrame(scores_data, ["student_id", "scores"])

df_bonus = df_scores.withColumn(
    "curved_scores",
    transform(col("scores"), lambda x: x + 5)
)

df_percent = df_scores.withColumn(
    "percentages",
    transform(col("scores"), lambda x: x / 100)
)

df_bonus.show()

Chaining Multiple Transformations

Combine multiple operations in a single transform:

from pyspark.sql.functions import col, transform, trim, lower, regexp_replace

messy_data = [
    (1, ["  Python  ", "SPARK!", " hadoop-eco "]),
    (2, ["Machine_Learning", "  AI  "])
]
df_messy = spark.createDataFrame(messy_data, ["id", "raw_tags"])

df_clean = df_messy.withColumn(
    "clean_tags",
    transform(
        col("raw_tags"),
        lambda x: regexp_replace(lower(trim(x)), "[^a-z0-9]", "")
    )
)

df_clean.show(truncate=False)

Using filter for Array Elements

Filter arrays to keep only elements matching a condition:

from pyspark.sql.functions import col, filter

df_filtered = df.withColumn(
    "long_tags",
    filter(col("tags"), lambda x: length(x) > 4)
)

df_high_scores = df_scores.withColumn(
    "passing_scores",
    filter(col("scores"), lambda x: x >= 80)
)

Aggregating Array Elements

Use aggregate for reduction operations across array elements:

from pyspark.sql.functions import col, aggregate
from pyspark.sql.types import IntegerType

df_totals = df_scores.withColumn(
    "total_score",
    aggregate(
        col("scores"),
        lit(0),  # Initial value
        lambda acc, x: acc + x  # Accumulator function
    )
)

df_totals.show()

Fallback: User-Defined Functions (UDF)

When built-in functions cannot express your logic, use UDFs as a last resort:

from pyspark.sql.functions import udf, col
from pyspark.sql.types import ArrayType, StringType

def custom_transform(arr):
    if arr is None:
        return None
    return [f"tag_{item.upper()[:3]}" for item in arr]

custom_udf = udf(custom_transform, ArrayType(StringType()))

df_custom = df.withColumn("custom_tags", custom_udf(col("tags")))
df_custom.show(truncate=False)

Common Array Functions Reference

Function Purpose Example
transform Apply function to each element Element-wise operations
filter Keep elements matching condition Remove nulls, threshold filtering
aggregate Reduce array to single value Sum, product, custom aggregation
array_contains Check if element exists Membership testing
size Get array length Validation, filtering
explode Convert array to rows Denormalization

Method Comparison

Approach Performance Use Case
transform() Excellent Standard element-wise operations
filter() Excellent Conditional element selection
aggregate() Excellent Reduction operations
Python UDF Poor Complex custom logic only
Pandas UDF Good Vectorized Python operations

By prioritizing native array functions over Python UDFs, you ensure your PySpark transformations remain performant and scalable across large distributed datasets.

Navigation