让我们说一个表A:
Year product rating
07/02/2018 A good
07/02/2017 B good
07/02/2016 A bad
07/02/2015 C medium
07/02/2016 C bad
在第一阶段,我希望获得下表:
product year score
A 07/02/2018 1
A 07/02/2016 3
B 07/02/2017 1
C 07/02/2016 3
C 07/02/2015 2
第二阶段:
product year score for oldest date
A 07/02/2016 3
B 07/02/2017 1
C 07/02/2015 2
最短的方法是什么? (排名,将分数从字符串更改为数字,aggeregate)。我可以一次性完成所有这些步骤吗?
谢谢
答案 0 :(得分:1)
首先需要将列映射到Integer值。 您可以使用地图 -
diz = {k:str(v) for k,v in zip(rating.keys(),rating.values())}
检查此replace values of one column in a spark df by dictionary key-values (pyspark)
然后使用排序/聚合来获得所需的输出。
答案 1 :(得分:0)
只是为了使Abhishek解决方案更具体,假设你有上面给出的数据框架。
第一阶段
import pyspark.sql.functions as fn
from pyspark.sql.types import *
# replace rating to score
df2 = df.na.replace({'good': '2', 'bad': '0', 'medium': '1'}, value=1, subset='rating')
# cast rating score to integer
df2 = df2.select('date', 'product', fn.col('rating').cast(IntegerType()).alias('score'))
# sorting by product and score
df2.sort(fn.col('product'), fn.desc('score')).show()
如果您想要升序排序,也可以使用fn.col('score')
。
第二阶段
与第一个完全相同。但是,您必须应用unix_timestamp
来解析日期并按产品和解析日期排序。
df2 = df.na.replace({'good': '2', 'bad': '0', 'medium': '1'}, value=1, subset='rating')
df2 = df2.select('date', 'product',
fn.col('rating').cast(IntegerType()).alias('score'),
fn.unix_timestamp('date', format='MM/dd/yyyy').alias('date_dt'))
df2 = df2.sort(fn.col('product'), fn.asc('date_dt'))
然后groupby
产品,先抓住date
和score
df2.groupby(fn.col('product')).agg(fn.first(fn.col('date')), fn.first(fn.col('score'))).show()
>>
+-------+------------------+-------------------+
|product|first(date, false)|first(score, false)|
+-------+------------------+-------------------+
| B| 07/02/2017| 2|
| C| 07/02/2015| 1|
| A| 07/02/2016| 0|
+-------+------------------+-------------------+