Pyspark:每个唯一ID的用户定义的弹性

时间:2019-04-04 16:21:36

标签: pyspark pyspark-sql

我正在研究价格弹性问题,我需要计算每个唯一ID的弹性

我的数据框看起来像

| id    | price  | items | 

| 101   |  5     | 10    |   
| 101   |  10    | 15    | 
| 101   |  12    | 20    | 
| 102   |  1     | 1     | 
| 102   |  3     | 7     | 

要找到弹性: 以101为例,价格发生了3个变化,这3个价格变化以及相应的项目变化应该是新的数据框。

1)价格变化5(5-> 10(或10-> 5))导致5个项目变化(10-> 15(或15-> 10)),因此对应的行将是pricechange = 5,itemschange = 5

2)价格变化7(5-> 12(或12-> 5))导致10个项目变化(10-> 20(或20-> 10)),因此对应的行将是pricechange = 7,itemschange = 10

3)价格变化2(10-> 12(或12-> 10))导致5个项目变化(15-> 20(或20-> 15)),因此对应的行将是pricechange = 2,itemschange = 5

数据框将被转换为:

| id    | pricechange  | itemschange | 

| 101   |  5           | 5           |   
| 101   |  7           | 10          | 
| 101   |  2           | 5           | 
| 102   |  2           | 6           |

2 个答案:

答案 0 :(得分:0)

这是您可以遵循的详细方法-

定义架构并为DF准备数据

 df = spark.createDataFrame([
            (101,5,10),
            (101,10,15),
            (101,12,20),
            (102,1,1),    
            (102,3,7)
        ],'id : int, price : int, item: int')

创建虚拟列等级以将每个ID与相同ID的所有其他记录进行比较

from pyspark.sql.window import Window
from pyspark.sql.functions import *

windowSpec = Window.partitionBy('id').orderBy('id')
rank = row_number().over(windowSpec).alias('rank')

df = df.withColumn("rank", rank)

最终逻辑-连接和过滤

df.alias('a').\
    join(df.alias('b'),on='id').\
    where('a.rank < b.rank').\
    selectExpr("a.id as id","b.price - a.price as price","b.item - a.item as item").\
    show()

恕我直言-最好贴出您到目前为止尝试过的内容以及问题所面临的错误/问题。这有助于获得更快更好的响应。

答案 1 :(得分:0)

您只需在Class<?>列上对DataFrame与其内部进行内部联接。为了避免重复记录,请定义一个id子句,该子句要求左侧DataFrame的价格大于右侧DataFrame的价格。

加入后,选择所需的列:

where

这比使用from pyspark.sql.functions import col df.alias("r").join(df.alias("l"), on="id")\ .where("l.price > r.price")\ .select( "id", (col("l.price") - col("r.price")).alias("pricechange"), (col("l.item") - col("r.item")).alias("itemschange"), ).show() #+---+-----------+-----------+ #| id|pricechange|itemschange| #+---+-----------+-----------+ #|101| 2| 5| #|101| 7| 10| #|101| 5| 5| #|102| 2| 6| #+---+-----------+-----------+ 更有效率。