当前位置: 首页 > 面试题库 >

Pyspark-重置条件下的累积总和

霍襦宗
2023-03-14
问题内容

我有这个数据框

+---+----+---+
|  A|   B|  C|
+---+----+---+
|  0|null|  1|
|  1| 3.0|  0|
|  2| 7.0|  0|
|  3|null|  1|
|  4| 4.0|  0|
|  5| 3.0|  0|
|  6|null|  1|
|  7|null|  1|
|  8|null|  1|
|  9| 5.0|  0|
| 10| 2.0|  0|
| 11|null|  1|
+---+----+---+

我需要做的是从C列开始累积值的总和,直到下一个值为零,然后重置累积总和,直到完成所有行。

预期产量:

+---+----+---+----+
|  A|   B|  C|   D|
+---+----+---+----+
|  0|null|  1|   1|
|  1| 3.0|  0|   0|
|  2| 7.0|  0|   0|
|  3|null|  1|   1|
|  4| 4.0|  0|   0|
|  5| 3.0|  0|   0|
|  6|null|  1|   1|
|  7|null|  1|   2|
|  8|null|  1|   3|
|  9| 5.0|  0|   0|
| 10| 2.0|  0|   0|
| 11|null|  1|   1|
+---+----+---+----+

我已经使用了该Window().rangeBetween函数并达到了期望的输出,但是问题是您无法定义固定的窗口范围,因为DataFrame可以连续五次显示数字1,有时只能是两次,依此类推。

我的问题与以下Pyspark非常相似:重置条件下的累积总和,但没有人回答。

要重现数据帧:

from pyspark.shell import sc
from pyspark.sql import Window
from pyspark.sql.functions import lag, when, sum

x = sc.parallelize([
    [0, None], [1, 3.], [2, 7.], [3, None], [4, 4.],
    [5, 3.], [6, None], [7, None], [8, None], [9, 5.], [10, 2.], [11, None]])
x = x.toDF(['A', 'B'])

# Transform null values into "1"
x = x.withColumn('C', when(x.B.isNull(), 1).otherwise(0))

问题答案:

创建一个临时列(grp),每当列C等于0(重置条件)时递增计数器,并将其用作累积总和的分区列。

import pyspark.sql.functions as f
from pyspark.sql import Window

x.withColumn(
    "grp", 
    f.sum((f.col("C") == 0).cast("int")).over(Window.orderBy("A"))
).withColumn(
    "D",
    f.sum(f.col("C")).over(Window.partitionBy("grp").orderBy("A"))
).drop("grp").show()
#+---+----+---+---+
#|  A|   B|  C|  D|
#+---+----+---+---+
#|  0|null|  1|  1|
#|  1| 3.0|  0|  0|
#|  2| 7.0|  0|  0|
#|  3|null|  1|  1|
#|  4| 4.0|  0|  0|
#|  5| 3.0|  0|  0|
#|  6|null|  1|  1|
#|  7|null|  1|  2|
#|  8|null|  1|  3|
#|  9| 5.0|  0|  0|
#| 10| 2.0|  0|  0|
#| 11|null|  1|  1|
#+---+----+---+---+


 类似资料:
  • 问题内容: 我正在尝试做的事情的广泛视角是,在预订系统被预订之日,找出整个系统中尚未进行的预订。这意味着计算存在的所有记录的数量,这些记录的后缀等于(或等于),按分组。请参阅以下假设示例,以获得更好的解释: 我想要结果: 但是我对如何构造查询完全不满意。有小费吗?谢谢! 编辑:为明确起见,number_of_reservations应该是该日期的预订数量,以及该日期之后几天的预订数量。换句话说,n

  • 问题内容: 我想对列进行累加,但是每当遇到0时就重置聚合值 这是我尝试做的一个例子: 该数据集: 给出以下内容: 问题答案: 在SQL Server 2008中,由于无法使用分析函数,因此受到了严重限制。以下方法效率不高,但可以解决您的问题: las,在SQL Server 2012之前,最有效的解决方案可能涉及游标。在SQL Server 2012+中,您只需执行以下操作:

  • 问题内容: 如果我使用这样的1或NaN命名: 我想计算该系列的总和,但应在NaN的位置将其重置(设置为零),如下所示: 理想情况下,我希望有一个矢量化解决方案! 我曾经在Matlab上看到过类似的问题: 在NaN上重置Matlabcumsum吗? 但我不知道如何翻译这行 问题答案: Matlab代码的简单Numpy翻译是这样的: 执行此代码将返回结果。此解决方案仅会与原始解决方案一样有效,但是如果

  • 问题内容: 我正在尝试为dellstore2数据库累计计算用户数。在这里和其他论坛上寻找答案时,我使用了这个 这返回 每个月是 看一下前几项,似乎总的来说还不错。但是当我跑步时 对于整个事情,我明白了 这与第一个输出11,681中的最后一项不一致。我猜上面的计算无法确定整个月的唯一性。什么是最快的计算方式(最好不使用自联接)? 问题答案: 除了直接从订单中选择之外,还可以使用如下子查询: 我认为这

  • 问题内容: 我有一个看起来像这样的表: 我想添加一个新的列,称为cumulative_sum,因此表如下所示: 是否有可以轻松完成此操作的MySQL更新语句?做到这一点的最佳方法是什么? 问题答案: 如果性能是一个问题,则可以使用MySQL变量: 或者,您可以删除该列并在每个查询中对其进行计算: 这以运行方式计算运行总和:)

  • 问题内容: 我已经实现了一定数量的所有素数的列表。我试图做的事情很难解释,所以我只用一些硬代码展示一下: 所以从本质上讲,我试图从上一个列表中按顺序取出一个元素,然后按指数倍增,然后将其追加到其他列表中。 我意识到我可以做到这一点,这可能会更容易: 我需要一些想法才能在某种程度上做到这一点。 问题答案: 您需要 累积产品 清单。这是一个简单的食谱: 另一种方法,使用itertools: 或者,也许