Apache spark 计算每组当前行中的值和第一行中的值之间的差值-pyspark

Apache spark 计算每组当前行中的值和第一行中的值之间的差值-pyspark,apache-spark,dataframe,pyspark,spark-dataframe,Apache Spark,Dataframe,Pyspark,Spark Dataframe,我有这个数据框: DataFrame[日期:string,t:string,周:string,a:bigint,b:bigint] 使用以下数据: +---------+--+--------+---+---+ |日期| t |周| a | b| +---------+--+--------+---+---+ |20180328 | 1 | 2018-W10 | 31 | 35| |20180328 | 1 | 2018-W11 | 18 | 37| |20180328 | 1 | 2018-

我有这个数据框:

DataFrame[日期:string,t:string,周:string,a:bigint,b:bigint]
使用以下数据:

+---------+--+--------+---+---+
|日期| t |周| a | b|
+---------+--+--------+---+---+
|20180328 | 1 | 2018-W10 | 31 | 35|
|20180328 | 1 | 2018-W11 | 18 | 37|
|20180328 | 1 | 2018-W12 | 19 | 37|
|20180328 | 1 | 2018-W13 | 19 | 38|
|20180328 | 1 | 2018-W14 | 20 | 38|
|20180328 | 1 | 2018-W15 | 22 | 39|
|20180328 | 1 | 2018-W16 | 23 | 39|
|20180328 | 1 | 2018-W17 | 24 | 40|
|20180328 | 1 | 2018-W18 | 25 | 40|
|20180328 | 1 | 2018-W19 | 25 | 41|
|20180328 | 1 | 2018-W20 | 26 | 41|
|20180328 | 1 | 2018-W21 | 26 | 41|
|20180328 | 1 | 2018-W22 | 26 | 41|
|20180328 | 2 | 2018-W10 | 14 | 26|
|20180328 | 2 | 2018-W11 | 82 | 33|
|20180328 | 2 | 2018-W12 | 87 | 36|
|20180328 | 2 | 2018-W13 | 89 | 39|
|20180328 | 2 | 2018-W14 | 10 | 45|
|20180328 | 2 | 2018-W15 | 10 | 45|
|20180328 | 2 | 2018-W16 | 11 | 48|
|20180328 | 2 | 2018-W17 | 11 | 55|
|20180328 | 2 | 2018-W18 | 11 | 60|
|20180328 | 2 | 2018-W19 | 11 | 70|
|20180328 | 2 | 2018-W20 | 11 | 79|
|20180328 | 2 | 2018-W21 | 11 | 86|
|20180328 | 2 | 2018-W22 | 12 | 93|
+---------+--+--------+---+---+
我想添加一个新列,对于每个日期和类型(column
t
),该行与column
b
的该日期的第一周之间的差异

大概是这样的:

+---------+--+--------+---+---+---+
|日期| t |周| a | b | h|
+---------+--+--------+---+---+---+
|20180328 | 1 | 2018-W10 | 31 | 35 | 0 |
|20180328 | 1 | 2018-W11 | 18 | 37 | 2|
|20180328 | 1 | 2018-W12 | 19 | 37 | 2|
|20180328 | 1 | 2018-W13 | 19 | 38 | 3|
|20180328 | 1 | 2018-W14 | 20 | 38 | 3|
|20180328 | 1 | 2018-W15 | 22 | 39 | 4|
|20180328 | 1 | 2018-W16 | 23 | 39 | 4|
|20180328 | 1 | 2018-W17 | 24 | 40 | 5|
|20180328 | 1 | 2018-W18 | 25 | 40 | 5|
|20180328 | 1 | 2018-W19 | 25 | 41 | 6|
|20180328 | 1 | 2018-W20 | 26 | 41 | 6|
|20180328 | 1 | 2018-W21 | 26 | 41 | 6 |
|20180328 | 1 | 2018-W22 | 26 | 41 | 6 |
|20180328 | 2 | 2018-W10 | 14 | 26 | 0 |
|20180328 | 2 | 2018-W11 | 82 | 33 | 7 |
|20180328 | 2 | 2018-W12 | 87 | 36 | 10 |
|20180328 | 2 | 2018-W13 | 89 | 39 | 13 |
|20180328 | 2 | 2018-W14 | 10 | 45 | 19 |
|20180328 | 2 | 2018-W15 | 10 | 45 | 19 |
|20180328 | 2 | 2018-W16 | 11 | 48 | 22 |
|20180328 | 2 | 2018-W17 | 11 | 55 | 29 |
|20180328 | 2 | 2018-W18 | 11 | 60 | 34 |
|20180328 | 2 | 2018-W19 | 11 | 70 | 44 |
|20180328 | 2 | 2018-W20 | 11 | 79 | 53 |
|20180328 | 2 | 2018-W21 | 11 | 86 | 60 |
|20180328 | 2 | 2018-W22 | 12 | 93 | 67 |
+---------+--+--------+---+---+---+

h列中的每个数字都是该类型在W10处的列('b')中的值。

您可以使用

按列
't'
划分,按列
'week'
排序。这是因为对周列进行排序将进行字典排序,
'W10'
将是组的第一个值。如果情况并非如此,则需要找到另一种方法对列进行排序,以使顺序符合您的要求

下面是一个精简的示例

数据=[
('20180328',1,'2018-W10',31,35),
('20180328',1,'2018-W11',18,37),
('20180328',1,'2018-W12',19,37),
('20180328',1,'2018-W13',19,38),
('20180328',1,'2018-W14',20,38),
('20180328',2,'2018-W10',14,26),
('20180328',2,'2018-W11',82,33),
('20180328',2,'2018-W12',87,36),
('20180328',2,'2018-W13',89,39)
]
df=sqlCtx.createDataFrame(数据,['date','t','week','a','b'])
df.show()
#+--------+---+--------+---+---+
#|日期| t |周| a | b|
#+--------+---+--------+---+---+
#|20180328 | 1 | 2018-W10 | 31 | 35|
#|20180328 | 1 | 2018-W11 | 18 | 37|
#|20180328 | 1 | 2018-W12 | 19 | 37|
#|20180328 | 1 | 2018-W13 | 19 | 38|
#|20180328 | 1 | 2018-W14 | 20 | 38|
#|20180328 | 2 | 2018-W10 | 14 | 26|
#|20180328 | 2 | 2018-W11 | 82 | 33|
#|20180328 | 2 | 2018-W12 | 87 | 36|
#|20180328 | 2 | 2018-W13 | 89 | 39|
#+--------+---+--------+---+---+
使用pyspark数据帧函数

定义窗口:

从pyspark.sql导入窗口
w=Window.partitionBy('t')。orderBy('week'))
使用窗口创建新列:

导入pyspark.sql.f函数
df=df.select('*',(f.col('b')-f.first('b')).over(w)).alias('h'))
df.show()
#+--------+---+--------+---+---+---+
#|日期| t |周| a | b | h|
#+--------+---+--------+---+---+---+
#|20180328 | 1 | 2018-W10 | 31 | 35 | 0|
#|20180328 | 1 | 2018-W11 | 18 | 37 | 2|
#|20180328 | 1 | 2018-W12 | 19 | 37 | 2|
#|20180328 | 1 | 2018-W13 | 19 | 38 | 3|
#|20180328 | 1 | 2018-W14 | 20 | 38 | 3|
#|20180328 | 2 | 2018-W10 | 14 | 26 | 0|
#|20180328 | 2 | 2018-W11 | 82 | 33 | 7|
#|20180328 | 2 | 2018-W12 | 87 | 36 | 10|
#|20180328 | 2 | 2018-W13 | 89 | 39 | 13|
#+--------+---+--------+---+---+---+
使用pyspark sql

以下是使用pyspark sql的等效操作:

df.RegisterEmptable('myTable'))
df=sqlCtx.sql(
“从myTable中选择*,(b-第一个(b)在(按t按周顺序划分))上作为h”
)
df.show()
#+--------+---+--------+---+---+---+
#|日期| t |周| a | b | h|
#+--------+---+--------+---+---+---+
#|20180328 | 1 | 2018-W10 | 31 | 35 | 0|
#|20180328 | 1 | 2018-W11 | 18 | 37 | 2|
#|20180328 | 1 | 2018-W12 | 19 | 37 | 2|
#|20180328 | 1 | 2018-W13 | 19 | 38 | 3|
#|20180328 | 1 | 2018-W14 | 20 | 38 | 3|
#|20180328 | 2 | 2018-W10 | 14 | 26 | 0|
#|20180328 | 2 | 2018-W11 | 82 | 33 | 7|
#|20180328 | 2 | 2018-W12 | 87 | 36 | 10|
#|20180328 | 2 | 2018-W13 | 89 | 39 | 13|
#+--------+---+--------+---+---+---+
相关的


您可以使用

按列
't'
划分,按列
'week'
排序。这是因为对周列进行排序将进行字典排序,
'W10'
将是组的第一个值。如果情况并非如此,则需要找到另一种方法对列进行排序,以使顺序符合您的要求

下面是一个精简的示例