给定一个包含“ProductId”、“Date”和“Price”列的 pyspark 数据框 df
,按“Date”排序并假设 func.first('Price) 的安全性如何')
将始终检索与最小日期相对应的价格?
我的意思是:会
df.orderBy('ProductId', 'Date').groupBy('ProductId').agg(func.first('Price'))
返回每个产品及时支付的第一个价格,而不会在分组时弄乱 orderBy
?
最佳答案
我不确定 groupBy()
是否保证维持顺序。但是,这里有一种替代方法可以实现您想要的效果。
使用pyspark.sql.Window
根据需要对 DataFrame 进行分区和排序。然后使用pyspark.sql.DataFrame.distinct()
删除重复的条目。
例如:
创建虚拟数据
data = [
(123, '2017-07-01', 50),
(123, '2017-01-01', 100),
(345, '2018-01-01', 20),
(123, '2017-03-01', 25),
(345, '2018-02-01', 33)
]
df = sqlCtx.createDataFrame(data, ['ProductId', 'Date', 'Price'])
df.show()
#+---------+----------+-----+
#|ProductId| Date|Price|
#+---------+----------+-----+
#| 123|2017-07-01| 50|
#| 123|2017-01-01| 100|
#| 345|2018-01-01| 20|
#| 123|2017-03-01| 25|
#| 345|2018-02-01| 33|
#+---------+----------+-----+
使用窗口
使用Window.partitionBy('ProductId').orderBy('Date')
:
import pyspark.sql.functions as f
from pyspark.sql import Window
df.select(
'ProductId',
f.first('Price').over(Window.partitionBy('ProductId').orderBy('Date')).alias('Price')
).distinct().show()
#+---------+-----+
#|ProductId|Price|
#+---------+-----+
#| 123| 100|
#| 345| 20|
#+---------+-----+
编辑
我找到了this scala post其中接受的答案说顺序被保留,尽管评论中存在与此相矛盾的讨论。
关于python - 在 pyspark 中对数据帧进行分组之前进行排序是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48950500/