我在本地计算机上使用Pyspark。我有一个火花数据框架,其中包含450万行和大约30,000种不同的股票。我需要计算每只股票随时间变化的百分比。我已经运行了orderBy,以便将所有股票归为一组(如下例所示)。
下面是一个简化的示例数据框。
df = spark.read.csv("stock_price.txt", header=True, inferSchema=True)
df.show()
**Company** **Price**
Company_A 100
Company_A 103
Company_A 105
Company_A 107
Company_B 23
Company_B 25
Company_B 28
Company_B 30
我想要的输出将是这样
**Company** **Price** **%_Change**
Company_A 100 0
Company_A 103 3%
Company_A 105 2%
Company_A 107 2%
Company_B 23 0
Company_B 25 9%
Company_B 28 12%
Company_B 30 7%
技巧(以我的观点)是建立一个可以完成两件事的代码: 1)确定每次列出新库存 2)开始计算该股票第二次观察的百分比变化,并继续计算百分比变化,直到最后一次观察。它需要从第二次观察开始,因为在第二次观察发生之前不会有百分比变化。
答案 0 :(得分:1)
我相信Windows是前往这里的方式
一些进口
from pyspark.sql.window import Window
from pyspark.sql.functions import lag
partitionBy('Company')将我们的库存保持在一起。我在这里按价格订购,但是可能要等到您的日期时间
win = Window.partitionBy('Company').orderBy('Price')
借助lag
更改了计算百分比,该百分比在窗口中获取了先前的值
df.withColumn('perc_change', (df.Price - lag(df['Price']).over(win))/100).show()
+---------+-----+-----------+
| Company|Price|perc_change|
+---------+-----+-----------+
|Company_B| 23| null|
|Company_B| 25| 0.02|
|Company_B| 28| 0.03|
|Company_B| 30| 0.02|
|Company_A| 100| null|
|Company_A| 103| 0.03|
|Company_A| 105| 0.02|
|Company_A| 107| 0.02|
+---------+-----+-----------+
答案 1 :(得分:1)
您可以使用window
操作来实现此目的,理想情况下,您可以对具有id
或timestamp
的列进行排序。例如,我使用company
作为排序键。
from pyspark.sql import functions as F
from pyspark.sql.window import Window
df = spark.read.csv("stock_price.txt", header=True, inferSchema=True)
price_window = Window.partitionBy("company").orderBy("company")
df = df.withColumn("prev_value", F.lag(df.price).over(price_window))
df = df.withColumn("diff", F.when(F.isnull(df.price - df.prev_value), 0).otherwise(df.price - df.prev_value))
+---------+-----+----------+----+
| company|price|prev_value|diff|
+---------+-----+----------+----+
|Company_B| 23| null| 0|
|Company_B| 25| 23| 2|
|Company_B| 28| 25| 3|
|Company_B| 30| 28| 2|
|Company_A| 100| null| 0|
|Company_A| 103| 100| 3|
|Company_A| 105| 103| 2|
|Company_A| 107| 105| 2|
+---------+-----+----------+----+