有人可以向我解释为什么这两个条件产生不同的输出(甚至不同的count())?
FIRST:
(df
.where(cond1)
.where((cond2) | (cond3))
.groupBy('id')
.agg(F.avg(F.column('col1')).alias('name'),
F.avg(F.column('col2')).alias('name'))
).count()
第二
(df
.groupBy('id')
.agg(F.avg(F.when(((cond2) | (cond3))) & (cond1),
F.column('col1'))).alias('name'),
F.avg(F.when(((cond2) | (cond3)) & (cond1),
F.column('col2'))).alias('name'))
).count()
答案 0 :(得分:0)
我只是想通了。 when()在找不到匹配时返回None,但None仍然是返回,这意味着聚合会考虑所有值。当与由同一列分组并且没有条件聚合的简单df进行比较时,结果是相同的。
另一方面,where()过滤DataFrame,因此聚合仅应用于DataFrame的过滤版本,因此结果数量较少
答案 1 :(得分:0)
在不知道条件是什么的情况下,我的理解是它们是不同的过程:在第一种情况下,您首先过滤行,您需要处理,按ID分组并获取过滤的平均值数据,结果让我们说x行。在第二种情况下,您首先按ID分组,不进行行过滤,并告诉spark添加名为“name”的列,该列保存条件平均值到分组的df。您没有有条件地过滤行,因此您现在有x +更多行(取决于您的条件)
(df
.where(cond1) # remove rows by applying cond1
.where((cond2) | (cond3)) # remove rows by applying cond2, 3
.groupBy('id') # group *remaining* rows by id
.agg(F.avg(F.column('col1')).alias('name'), # then get the average
F.avg(F.column('col2')).alias('name'))
).count()
可是:
(df
.groupBy('id') # group initial data by id
.agg(F.avg(F.when(((cond2) | (cond3))) & (cond1), # add a column to the grouped data that computes average conditionally
F.column('col1'))).alias('name'),
F.avg(F.when(((cond2) | (cond3)) & (cond1),
F.column('col2'))).alias('name'))
).count()
# the agg does not change the number of the rows.
希望这会有所帮助(我认为你已经弄明白了:))。祝你好运!