Pyspark SQL:在数据透视表中保留只有空值的条目
Posted
技术标签:
【中文标题】Pyspark SQL:在数据透视表中保留只有空值的条目【英文标题】:Pyspark SQL: Keep entries with only null values in pivot table 【发布时间】:2018-01-27 17:19:17 【问题描述】:我正在尝试在 PySpark SQL 数据帧上创建一个数据透视表,它不会删除空值。我的输入表结构如下:
我在 Python 2 和 spark 2.1 下运行 IBM Data Science Experience 云中的所有内容。
在 pandas 数据帧上执行此操作时,“dropna=false”参数给了我想要的结果。
table= pd.pivot_table(ratings,columns=['movieId'],index=[ 'monthyear','userId'], values='rating', dropna=False)
作为输出,我得到以下信息:
在 PySpark SQL 中,我目前正在使用以下命令:
ratings_pivot = spark_df.groupBy('monthyear','userId').pivot('movieId').sum("rating").show()
作为输出,我得到以下信息:
如您所见,没有显示所有只有空值的条目。是否有可能在 SQL 中使用类似 dropna=false 的东西?由于这是非常具体的,我在互联网上找不到任何相关信息。
我刚刚提取了一个小数据集进行复制:
df = spark.createDataFrame([("1", 30, 2.5,200912), ("1", 32, 3.0,200912), ("2", 40, 4.0,201002), ("3", 45, 2.5,200002)], ("userID", "movieID", "rating", "monthyear"))
df.show()
+------+-------+------+---------+
|userID|movieID|rating|monthyear|
+------+-------+------+---------+
| 1| 30| 2.5| 200912|
| 1| 32| 3.0| 200912|
| 2| 40| 4.0| 201002|
| 3| 45| 2.5| 200002|
+------+-------+------+---------+
如果我现在运行数据透视查询,我会得到以下结果:
df.groupBy("monthyear","UserID").pivot("movieID").sum("rating").show()
+---------+------+----+----+----+----+
|monthyear|UserID| 30| 32| 40| 45|
+---------+------+----+----+----+----+
| 201002| 2|null|null| 4.0|null|
| 200912| 1| 2.5| 3.0|null|null|
| 200002| 3|null|null|null| 2.5|
+---------+------+----+----+----+----+
我现在想要的是,结果如下所示:
+---------+------+----+----+----+----+
|monthyear|UserID| 30| 32| 40| 45|
+---------+------+----+----+----+----+
| 201002| 2|null|null| 4.0|null|
| 200912| 2|null|null|null|null|
| 200002| 2|null|null|null|null|
| 200912| 1| 2.5| 3.0|null|null|
| 200002| 1|null|null|null|null|
| 201002| 1|null|null|null|null|
| 200002| 3|null|null|null| 2.5|
| 200912| 3|null|null|null|null|
| 201002| 3|null|null|null|null|
+---------+------+----+----+----+----+
【问题讨论】:
感谢您的提示,我编辑了我的问题以使其可重现。 【参考方案1】:Spark 提供了类似的功能,因为它无法扩展。 pivot
一个人就够贵了。可以通过外部连接手动完成:
n = 20 # Adjust value depending on the data
wide = (df
# Get unique months
.select("monthyear")
.distinct()
.coalesce(n) # Coalesce to avoid partition number "explosion"
# Same as above for UserID and get Cartesian product
.crossJoin(df.select("UserID").distinct().coalesce(n))
# Join with pivoted data
.join(
df.groupBy("monthyear", "UserID")
.pivot("movieID")
.sum("rating"),
["monthyear", "UserID"],
"leftouter"))
wide.show()
# +---------+------+----+----+----+----+
# |monthyear|UserID| 30| 32| 40| 45|
# +---------+------+----+----+----+----+
# | 201002| 3|null|null|null|null|
# | 201002| 2|null|null| 4.0|null|
# | 200002| 1|null|null|null|null|
# | 200912| 1| 2.5| 3.0|null|null|
# | 200002| 3|null|null|null| 2.5|
# | 200912| 2|null|null|null|null|
# | 200912| 3|null|null|null|null|
# | 201002| 1|null|null|null|null|
# | 200002| 2|null|null|null|null|
# +---------+------+----+----+----+----+
【讨论】:
非常好。非常感谢!这正是我想要的。【参考方案2】:Spark 确实为行和列保留了所有 null
值的条目:
Spark 2.1:
Welcome to
____ __
/ __/__ ___ _____/ /__
_\ \/ _ \/ _ `/ __/ '_/
/__ / .__/\_,_/_/ /_/\_\ version 2.1.1
/_/
Using Python version 3.6.4 (default, Dec 21 2017 21:42:08)
SparkSession available as 'spark'.
In [1]: df = spark.createDataFrame([("a", 1, 4), ("a", 2, 2), ("b", 3, None), (None, 4, None)], ("x", "y", "z"))
In [2]: df.groupBy("x").pivot("y").sum("z").show()
+----+----+----+----+----+
| x| 1| 2| 3| 4|
+----+----+----+----+----+
|null|null|null|null|null|
| b|null|null|null|null|
| a| 4| 2|null|null|
+----+----+----+----+----+
Spark 2.2:
Welcome to
____ __
/ __/__ ___ _____/ /__
_\ \/ _ \/ _ `/ __/ '_/
/__ / .__/\_,_/_/ /_/\_\ version 2.2.1
/_/
Using Python version 3.6.4 (default, Dec 21 2017 21:42:08)
SparkSession available as 'spark'.
In [1]: df = spark.createDataFrame([("a", 1, 4), ("a", 2, 2), ("b", 3, None), (None, 4, None)], ("x", "y", "z"))
In [2]: df.groupBy("x").pivot("y").sum("z").show()
+----+----+----+----+----+
| x| 1| 2| 3| 4|
+----+----+----+----+----+
|null|null|null|null|null|
| b|null|null|null|null|
| a| 4| 2|null|null|
+----+----+----+----+----+
Spark 2.3:
Welcome to
____ __
/ __/__ ___ _____/ /__
_\ \/ _ \/ _ `/ __/ '_/
/__ / .__/\_,_/_/ /_/\_\ version 2.3.0
/_/
Using Python version 3.6.4 (default, Dec 21 2017 21:42:08)
SparkSession available as 'spark'.
In [1]: df = spark.createDataFrame([("a", 1, 4), ("a", 2, 2), ("b", 3, None), (None, 4, None)], ("x", "y", "z"))
In [2]: df.groupBy("x").pivot("y").sum("z").show()
+----+----+----+----+----+
| x| 1| 2| 3| 4|
+----+----+----+----+----+
|null|null|null|null|null|
| b|null|null|null|null|
| a| 4| 2|null|null|
+----+----+----+----+----+
【讨论】:
非常感谢您的回答。我正在使用 Spark 2.1 版。我在最后一部分编辑了我的问题以使其更清楚。以上是关于Pyspark SQL:在数据透视表中保留只有空值的条目的主要内容,如果未能解决你的问题,请参考以下文章
SqlServer中的数据根据该表中某字段的值的结果决定是不是显示