【问题标题】:cumulative product in pySpark data framepySpark 数据框中的累积积
【发布时间】:2019-05-03 07:55:15
【问题描述】:

我有以下 spark DataFrame:

+---+---+
|  a|  b|
+---+---+     
|  1|  1|  
|  1|  2|  
|  1|  3|
|  1|  4|
+---+---+  

我想创建另一个名为"c" 的列,其中包含“b”对“a”的累积乘积。生成的 DataFrame 应如下所示:

+---+---+---+
|  a|  b|  c|
+---+---+---+     
|  1|  1|  1|
|  1|  2|  2|
|  1|  3|  6|
|  1|  4| 24|
+---+---+---+  

如何做到这一点?

【问题讨论】:

  • 嗨,欢迎来到 Stackoverflow!如果您在提出新问题之前可以read these guidelines,那就太好了。谢谢。

标签: apache-spark pyspark apache-spark-sql


【解决方案1】:

这是一种不使用用户定义函数的替代方法

df = spark.createDataFrame([(1, 1), (1, 2), (1, 3), (1, 4), (1, 5)], ['a', 'b'])
wind = Window.partitionBy("a").rangeBetween(Window.unboundedPreceding, Window.currentRow).orderBy("b")
df2 = df.withColumn("foo", collect_list("b").over(wind))
df2.withColumn("foo2", expr("aggregate(foo, cast(1 as bigint), (acc, x) -> acc * x)")).show()

+---+---+---------------+----+
|  a|  b|            foo|foo2|
+---+---+---------------+----+
|  1|  1|            [1]|   1|
|  1|  2|         [1, 2]|   2|
|  1|  3|      [1, 2, 3]|   6|
|  1|  4|   [1, 2, 3, 4]|  24|
|  1|  5|[1, 2, 3, 4, 5]| 120|
+---+---+---------------+----+

如果你真的不关心精度,你可以构建一个更短的版本

import pyspark.sql.functions as psf

df.withColumn("foo", psf.exp(psf.sum(psf.log("b")).over(wind))).show()
+---+---+------------------+
|  a|  b|               foo|
+---+---+------------------+
|  1|  1|               1.0|
|  1|  2|               2.0|
|  1|  3|               6.0|
|  1|  4|23.999999999999993|
|  1|  5|119.99999999999997|
+---+---+------------------

【讨论】:

    【解决方案2】:

    您必须设置一个订单列。在您的情况下,我使用了“b”列

    from pyspark.sql import functions as F, Window, types
    from functools import reduce
    from operator import mul
    
    df = spark.createDataFrame([(1, 1), (1, 2), (1, 3), (1, 4), (1, 5)], ['a', 'b'])
    
    order_column = 'b'
    
    window = Window.orderBy(order_column)
    
    expr = F.col('a') * F.col('b')
    
    mul_udf = F.udf(lambda x: reduce(mul, x), types.IntegerType())
    
    df = df.withColumn('c', mul_udf(F.collect_list(expr).over(window)))
    
    df.show()
    
    +---+---+---+
    |  a|  b|  c|
    +---+---+---+
    |  1|  1|  1|
    |  1|  2|  2|
    |  1|  3|  6|
    |  1|  4| 24|
    |  1|  5|120|
    +---+---+---+
    

    【讨论】:

      【解决方案3】:

      你的回答与此类似。

      import pandas as pd
      df = pd.DataFrame({'v':[1,2,3,4,5,6]})
      df['prod'] = df.v.cumprod()
         v   prod
      0  1     1
      1  2     2
      2  3     6
      3  4    24
      4  5   120
      5  6   720
      

      【讨论】:

      • 谢谢你 prathik .. 但我想在 pyspark 中进行此操作
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多