我在Pyspark中有一个数据框,我想在该数据框上计算列中的空值以及相应列的不同值,即非空值
这是我拥有的数据框
trans_date transaction_id transaction_id1
2016-01-01 1 1
2016-01-01 2 null
2016-01-01 null 3
我想在月份和年份进行汇总,并生成类似这样的内容
| month | year | id_count_in_x_not_in_y | id_count_in_y_not_in_x | ids_in_x | ids_in_y |
df.groupBy(F.month(F.col("trans_date")).alias("MONTH"), \
F.year(F.col("trans_date")).alias("YEAR")) \
.agg(*(F.sum(F.col(c).isNull().cast("int")).alias(c) for c in columns))\
.show()
这就是我在代码方面的能力,但是似乎并不能给我很好的答案。同样,应该如何在同一代码中进行非空计数。 任何帮助,将不胜感激。 谢谢!
答案 0 :(得分:1)
首先,按年份和月份分组。我们可以计算每列中每组的空值和非空值,并将它们转换为int后求和;那部分很简单。
对于出现在一个列中但不在另一列中的元素的计数,我们可以使用collect_set
,它将{唯一的元素}与array_except
一起聚集到单个数组中:
from pyspark.sql import functions as F
from pyspark.sql.types import IntegerType
result = (df
.groupBy(F.year('date').alias('year'), F.month('date').alias('month'))
.agg(F.sum(F.isnull('x').cast(IntegerType())).alias('x_null'),
F.sum(F.isnull('y').cast(IntegerType())).alias('y_null'),
F.sum((~F.isnull('x')).cast(IntegerType())).alias('x_not_null'),
F.sum((~F.isnull('y')).cast(IntegerType())).alias('y_not_null'),
F.collect_set('x').alias('x_unique'),
F.collect_set('y').alias('y_unique'))
.withColumn('x_not_in_y_count', F.size(F.array_except('x_unique', 'y_unique')))
.withColumn('y_not_in_x_count', F.size(F.array_except('y_unique', 'x_unique')))
.drop('x_unique', 'y_unique')
.orderBy('year', 'month')
)
给出以下测试数据:
+----------+----+----+
| date| x| y|
+----------+----+----+
|1991-01-01|null| 2|
|1991-01-02| 1|null|
|1991-01-03| 2| 3|
|1991-02-01|null| 1|
|1991-02-02|null| 2|
+----------+----+----+
这是输出:
+----+-----+------+------+----------+----------+----------------+----------------+
|year|month|x_null|y_null|x_not_null|y_not_null|x_not_in_y_count|y_not_in_x_count|
+----+-----+------+------+----------+----------+----------------+----------------+
|1991| 1| 1| 1| 2| 2| 1| 1|
|1991| 2| 2| 0| 0| 2| 0| 2|
+----+-----+------+------+----------+----------+----------------+----------------+