我正在研究价格弹性问题,我需要计算每个唯一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 |
答案 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|
#+---+-----------+-----------+
更有效率。