计算当前行中的值与每组第一行中的值之间的差异 - pyspark

时间:2018-03-29 12:16:10

标签: apache-spark dataframe pyspark spark-dataframe

我有这个DataFrame:

DataFrame[date: string, t: string, week: string, a: bigint, b: bigint]

使用以下数据:

+---------+--+--------+---+---+
|date     |t |week    |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 |
+---------+--+--------+---+---+

我想添加一个新列,对于每个日期和类型(列t),该行与该列b的该日期的第一周之间的差异。

这样的事情:

+---------+--+--------+---+---+---+
|date     |t |week    |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列中的每个数字都是col中的值(' b') - 此类型在W10的col(' b')中的值。

1 个答案:

答案 0 :(得分:1)

您可以使用pyspark.sql.Window.

完成此操作

按列new Date($.now()); 进行分区,按列't'排序。这样做是因为对您的周列进行排序将执行字典排序,'week'将是您的组的第一个值。如果不是这种情况,您需要找到另一种方法对列进行排序,以便订单符合您的要求。

这是一个精简的例子。

'W10'

使用pyspark DataFrame函数

定义窗口:

data = [
    ('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(data, ['date', 't', 'week', 'a', 'b'])
df.show()
#+--------+---+--------+---+---+
#|    date|  t|    week|  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|
#+--------+---+--------+---+---+

使用Window创建新列:

from pyspark.sql import Window   
w = Window.partitionBy('t').orderBy('week')

使用pyspark-sql

这是使用pyspark-sql的等效操作:

import pyspark.sql.functions as f

df = df.select('*', (f.col('b') - f.first('b').over(w)).alias('h'))
df.show()
#+--------+---+--------+---+---+---+
#|    date|  t|    week|  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|
#+--------+---+--------+---+---+---+

相关