【发布时间】:2022-01-13 13:26:32
【问题描述】:
我想在 Pyspark 的多列上进行前向填充。 如果列的起始值为“NaN”,则将其替换为 0。 下面是我的 DF 的样子。
| start_timestamp | Column1 | Column2 | Column3 | Column4 |
|---|---|---|---|---|
| 2020-11-02 08:51:50 | 2 | null | null | null |
| 2020-11-02 09:14:29 | null | null | null | 40 |
| 2020-11-02 09:18:32 | null | 4 | 2 | null |
| 2020-11-02 09:32:42 | 4 | null | null | null |
| 2020-11-03 13:06:03 | null | null | null | 20 |
| 2020-11-03 13:10:01 | 6 | null | 4 | null |
| 2020-11-03 13:54:38 | null | 5 | null | null |
| 2020-11-03 14:46:25 | null | null | null | null |
| 2020-11-03 14:57:31 | 7 | null | null | 10 |
| 2020-11-03 15:07:07 | 8 | 7 | null | null |
预期的 DF 为:
| start_timestamp | Column1 | Column2 | Column3 | Column4 |
|---|---|---|---|---|
| 2020-11-02 08:51:50 | 2 | 0 | 0 | 0 |
| 2020-11-02 09:14:29 | 2 | 0 | 0 | 40 |
| 2020-11-02 09:18:32 | 2 | 4 | 2 | 40 |
| 2020-11-02 09:32:42 | 4 | 4 | 2 | 40 |
| 2020-11-03 13:06:03 | 4 | 4 | 2 | 20 |
| 2020-11-03 13:10:01 | 6 | 4 | 4 | 20 |
| 2020-11-03 13:54:38 | 6 | 5 | 4 | 20 |
| 2020-11-03 14:46:25 | 6 | 5 | 4 | 20 |
| 2020-11-03 14:57:31 | 7 | 5 | 4 | 10 |
| 2020-11-03 15:07:07 | 8 | 7 | 4 | 10 |
下面是我在stackoverflow上尝试过的代码:
from pyspark.sql import Window
from pyspark.sql.functions import last,first
from pyspark.sql.functions import col, max as max_, min as min_
import sys
def stringReplaceFunc(x, y):
return F.when(x != y, x).otherwise(F.lit(None)) # replace with NULL
def forwardFillImputer(df, cols=[], partitioner="start_timestamp", value="null"):
for i in cols:
window = Window\
.partitionBy(F.month(partitioner))\
.orderBy(partitioner)\
.rowsBetween(-sys.maxsize, 0)
df= df\
.withColumn(i, stringReplaceFunc(F.col(i), value))
fill = F.last(df[i], ignorenulls=True).over(window)
df= df.withColumn(i, fill)
return df
df= forwardFillImputer(df, cols=[i for i in df.columns])
代码不起作用,请告诉我我在做什么错误。请让我知道是否有任何替代解决方案。谢谢。
【问题讨论】:
-
@thePurplePython 嗨找到了你的解决方案,你能帮我解决这个问题吗?
标签: apache-spark pyspark apache-spark-sql time-series