Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 对于每一天x,对于z列中缺少的每个唯一值y,创建一行,日期=x,z=y的最新值_Sql_Apache Spark_Pyspark_Apache Spark Sql - Fatal编程技术网

Sql 对于每一天x,对于z列中缺少的每个唯一值y,创建一行,日期=x,z=y的最新值

Sql 对于每一天x,对于z列中缺少的每个唯一值y,创建一行,日期=x,z=y的最新值,sql,apache-spark,pyspark,apache-spark-sql,Sql,Apache Spark,Pyspark,Apache Spark Sql,我有一个pyspark数据框,它说明了一个项目在哪个日期有特定大小的库存。表的复合键是[日期,大小]。如果项目具有n大小,则每个日期可以存在0到n行 input = spark.createDataFrame([ # Day 1: Row for all sizes [1, 1, 10], [1, 2, 10], [1, 3, 10], # Day 2: Row for one size [2, 1, 8], # Day 3: Row fo

我有一个pyspark数据框,它说明了一个项目在哪个日期有特定大小的库存。表的复合键是[日期,大小]。如果项目具有
n
大小,则每个日期可以存在0到
n

input = spark.createDataFrame([
    # Day 1: Row for all sizes
    [1, 1, 10],
    [1, 2, 10],
    [1, 3, 10],
    # Day 2: Row for one size
    [2, 1, 8],
    # Day 3: Row for no size
    # Day 4: Row for two sizes
    [4, 1, 7],
    [4, 2, 9],
], ["Date", "Size", "Stock"])
例如,在第二天,总共售出了两件1号商品,将该尺寸商品的库存从10件减少到8件。当天没有1号或3号的交易

我想计算每个
日期
该商品的
库存量。预期的输出如下所示:

expected = spark.createDataFrame([
    # Day 1
    [1, 1, 10],
    [1, 2, 10],
    [1, 3, 10],
    # Day 2
    [2, 1, 8],
    [2, 2, 10],
    [2, 3, 10],
    # Day 3
    [3, 1, 8],
    [3, 2, 10],
    [3, 3, 10],
    # Day 4
    [4, 1, 7],
    [4, 2, 9],
    [4, 3, 10],
], ["Date", "Size", "Stock"])

如何实现这一点?

这个想法是从最小和最大日期生成一系列日期,交叉连接以获得日期和大小的组合列表,左连接到原始数据帧,并使用
last
ignoreNulls
设置为
True
获取以前的股票价值

from pyspark.sql import functions as F, Window

df = input.agg(F.expr('sequence(min(Date), max(Date)) as Date')).select(F.explode('Date').alias('Date'))

result = df.crossJoin(
    input.select('Size').distinct().repartition(10)
).join(
    input, 
    ['Date', 'Size'], 
    'left'
).withColumn(
    'Stock', 
    F.last('Stock', True).over(Window.partitionBy('Size').orderBy('Date'))
)

result.orderBy('Date', 'Size').show()
+----+----+-----+
|Date|Size|Stock|
+----+----+-----+
|   1|   1|   10|
|   1|   2|   10|
|   1|   3|   10|
|   2|   1|    8|
|   2|   2|   10|
|   2|   3|   10|
|   3|   1|    8|
|   3|   2|   10|
|   3|   3|   10|
|   4|   1|    7|
|   4|   2|    9|
|   4|   3|   10|
+----+----+-----+