Java Spark:如何在列的一部分上构建半加性度量或聚合和?
我试图在spark中重现我在传统BI中所做的一些分析。使用的技术术语是如何构建半加性度量,但如果我解释这意味着什么,可能会有所帮助 例如,假设我每天都有一份股票持有量清单。昨天我有100个,今天我有50个。这是一个半累加度量,因为你没有150。你有50个。所以你只想总结一下今天的情况。但是,像销售额这样的东西是完全相加的,比如说,你可以把全年的销售额加起来 所以问题是如何使用agg和sum构建一个半加性度量?我该如何编写agg语句来同时显示半加性和全加性度量?例如:Java Spark:如何在列的一部分上构建半加性度量或聚合和?,java,apache-spark,apache-spark-sql,Java,Apache Spark,Apache Spark Sql,我试图在spark中重现我在传统BI中所做的一些分析。使用的技术术语是如何构建半加性度量,但如果我解释这意味着什么,可能会有所帮助 例如,假设我每天都有一份股票持有量清单。昨天我有100个,今天我有50个。这是一个半累加度量,因为你没有150。你有50个。所以你只想总结一下今天的情况。但是,像销售额这样的东西是完全相加的,比如说,你可以把全年的销售额加起来 所以问题是如何使用agg和sum构建一个半加性度量?我该如何编写agg语句来同时显示半加性和全加性度量?例如: val stocks = (
val stocks = (Seq(
("2019-05-01", 1, "FB", 1058.45, 100000),
("2019-05-01", 1, "NVDA", 40058.45, 150000),
("2019-05-03", 1, "FB", 8058.45, 80000),
("2019-05-04", 1, "FB", 11058.45, 75000), // Latest FB entry for account 1
("2019-05-05", 1, "NVDA", 50058.45, 125000), // Latest NVDA entry for account 1
("2019-05-01", 2, "FB", 1058.45, 200000),
("2019-05-02", 2, "NVDA", 5058.45, 125000),
("2019-05-03", 2, "NVDA", 5058.45, 115000),
("2019-05-05", 2, "FB", 1058.45, 65000), // latest FB entry for account 2
("2019-05-06", 2, "NVDA", 5058.45, 105000) // latest NVDA entry for account 2
).toDF("date", "symbol", "account", "sale", "current_holdings"))
stocks
.groupBy( stocks.col("symbol") )
.add( sum("earnings"), sum("current_holdings") )
.show()
这将产生什么:
+------+---------+----------------+
|symbol|sale |current_holdings|
+------+---------+----------------+
| FB| 34291.80| 520000.0|
| NDVA|105292.20| 525500.0|
+------+---------+----------------+
+------+---------+----------------+
|symbol|sale |current_holdings|
+------+---------+----------------+
| FB| 34291.80| 140000|
| NDVA|105292.20| 230000|
+------+---------+----------------+
应产生:
+------+---------+----------------+
|symbol|sale |current_holdings|
+------+---------+----------------+
| FB| 34291.80| 520000.0|
| NDVA|105292.20| 525500.0|
+------+---------+----------------+
+------+---------+----------------+
|symbol|sale |current_holdings|
+------+---------+----------------+
| FB| 34291.80| 140000|
| NDVA|105292.20| 230000|
+------+---------+----------------+
在“预期”中,差异仅存在于“当前_控股”列中,该列将汇总所有账户的所有最新分录。因此,为FB添加最新条目时,您会得到:
FB = 75000 + 65000
NVDA = 125000 + 105000
我看过WindowFunctions,但除了分区中的特定索引外,我看不到如何指定求和的条件,如果说我需要对特定月份的所有内容求和,这将很困难。Spark是如何做到这一点的
附言:
请原谅这个奇怪的例子,我不得不把它改编成供公众观看
PSS:
我也很难做到这一点,因为每个帐户/符号的最新日期不符合可预测的边界。在我的具体情况下,我实际上试图总结出只属于给定时间段年、季度等最后一个月的情况。我希望这是一个更简单的情况,但我想充分探索半加法用例,所以我使问题变得困难。PySpark解决方案可以修改为其等效的Scala代码 使用row_number对每个帐户的行进行编号,按日期的描述顺序使用符号,并对每组第一行的保留值求和
w=Window.partitionBy(stocks.account,stocks.symbol).orderBy(stocks.date.desc())
stocks = stocks.withColumn('rnum',row_number().over(w))
w1 = Window.partitionBy(stocks.symbol)
stocks = stocks.withColumn('sales',sum(stocks.sale).over(w1)).withColumn('holdings',sum(when(stocks.rnum==1,stocks.current_holdings).otherwise(0)).over(w1))
#Final selection
stocks.select(stocks.symbol,stocks.sales,stocks.holdings).distinct().show()
你能更详细地解释一下逻辑吗?好的,我认为这应该有助于更清楚地说明如何求和这些值以匹配预期值。