使用条件计数来旋转scala数据帧

时间:2018-01-02 17:07:49

标签: scala apache-spark dataframe apache-spark-sql spark-dataframe

我想汇总这个DataFrame并计算观察数量,其值小于或等于" BUCKET"每个级别的字段。例如:

val myDF = Seq(
  ("foo", 0),
  ("foo", 0),
  ("bar", 0),
  ("foo", 1),
  ("foo", 1),
  ("bar", 1),
  ("foo", 2),
  ("bar", 2),
  ("foo", 3),
  ("bar", 3)).toDF("COL1", "BUCKET")

  myDF.show

+----+------+
|COL1|BUCKET|
+----+------+
| foo|     0|
| foo|     0|
| bar|     0|
| foo|     1|
| foo|     1|
| bar|     1|
| foo|     2|
| bar|     2|
| foo|     3|
| bar|     3|
+----+------+

我可以使用以下代码计算匹配每个存储桶值的观察次数:

 myDF.groupBy("COL1").pivot("BUCKET").count.show
+----+---+---+---+---+
|COL1|  0|  1|  2|  3|
+----+---+---+---+---+
| bar|  1|  1|  1|  1|
| foo|  2|  2|  1|  1|
+----+---+---+---+---+

但是我想用" BUCKET"中的值来计算行数。旋转后小于或等于最终标题的字段,如下所示:

+----+---+---+---+---+
|COL1|  0|  1|  2|  3|
+----+---+---+---+---+
| bar|  1|  2|  3|  4|
| foo|  2|  4|  5|  6|
+----+---+---+---+---+

2 个答案:

答案 0 :(得分:3)

您可以使用窗口功能实现此目的,如下所示:

COL1

您在此处指定的是,您希望执行观察计数,在窗口中按照键(在这种情况下为myDF. select( $"COL1", $"BUCKET", count($"BUCKET").over(partitionBy($"COL1").orderBy($"BUCKET")).as("ROLLING_COUNT")). show() +----+------+-------------+ |COL1|BUCKET|ROLLING_COUNT| +----+------+-------------+ | bar| 0| 1| | bar| 1| 2| | bar| 2| 3| | bar| 3| 4| | foo| 0| 2| | foo| 0| 2| | foo| 1| 4| | foo| 1| 4| | foo| 2| 5| | foo| 3| 6| +----+------+-------------+ )进行分区。通过指定排序,您还可以在窗口上滚动计数,从而获得您希望在最终结果中旋转的结果。

这是应用窗口函数的结果:

COL1

最后,通过BUCKET进行分组,转移state()并获得滚动计数的第一个结果(任何人都会很好,因为所有这些都适用于整个窗口),最后获得你想要的结果。

在某种程度上,窗口函数与分组上的聚合非常相似,但更灵活,更强大。这只是触及窗口函数的表面,你可以通过查看this introductory reading来深入挖掘。

答案 1 :(得分:3)

这是通过使用findViewById(R.id.yourParentViewId).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { editText.requestFocus(); } }); 遍历枢轴BUCKET值列来聚合计数来获得滚动计数的一种方法。请注意,{DataFrame,Int)的元组用于foldLeft转换DataFrame以及在前一次迭代中存储计数:

foldLeft