在 PySpark 中,可以使用 pivot()
方法实现类似 Excel 数据透视表的功能。以下是详细操作步骤和示例:
df.groupBy([行维度列]) \
.pivot([列维度列]) \
.agg([聚合函数]) \
.fillna(0) # 可选,填充空值
假设有以下 DataFrame (sales_df
):
+-------+----------+------+-------+
|region | product | year | sales |
+-------+----------+------+-------+
| North | A | 2022 | 100 |
| North | B | 2022 | 200 |
| South | A | 2023 | 150 |
| South | C | 2023 | 300 |
+-------+----------+------+-------+
pivot_df = sales_df.groupBy("region") \
.pivot("product") \
.sum("sales") \
.fillna(0)
# 结果:
+-------+---+---+---+
|region | A | B | C |
+-------+---+---+---+
| North |100|200|0 |
| South |150|0 |300|
+-------+---+---+---+
from pyspark.sql.functions import sum
pivot_df = sales_df.groupBy("region", "year") \
.pivot("product") \
.agg(sum("sales")) \
.fillna(0)
# 结果:
+-------+----+---+---+---+
|region|year| A| B| C|
+-------+----+---+---+---+
| North|2022|100|200| 0|
| South|2023|150| 0|300|
+-------+----+---+---+---+
from pyspark.sql.functions import avg, count
pivot_df = sales_df.groupBy("region") \
.pivot("product") \
.agg(
avg("sales").alias("avg_sales"),
count("sales").alias("count_sales")
)
# 结果列的命名格式:product_聚合函数(如 A_avg_sales)
性能优化:如果列维度(pivot
列)的唯一值过多,可能导致性能问题。可通过以下方法优化:
提前过滤不必要的值:df.filter(df.column.isin(["A", "B"]))
设置配置:spark.conf.set("spark.sql.pivotMaxValues", 10000)
空值处理:使用 .fillna()
填充默认值(如 0)。
动态列名:如果列名动态生成,建议后续通过 select()
重命名列。
from pyspark.sql import SparkSession
from pyspark.sql.functions import sum
spark = SparkSession.builder.appName("PivotDemo").getOrCreate()
data = [
("North", "A", 2022, 100),
("North", "B", 2022, 200),
("South", "A", 2023, 150),
("South", "C", 2023, 300)
]
columns = ["region", "product", "year", "sales"]
sales_df = spark.createDataFrame(data, columns)
# 执行透视
pivot_df = sales_df.groupBy("region") \
.pivot("product") \
.agg(sum("sales")) \
.fillna(0)
pivot_df.show()
通过以上方法,你可以在 PySpark 中灵活实现数据透视功能。如果需要更复杂的逻辑(如多层嵌套聚合),可以结合 groupBy
和多个聚合函数组合使用。