我有一个pyspark数据框,其中包含客户,天数和交易类型的列表。
+----------+-----+------+
| Customer | Day | Type |
+----------+-----+------+
| A | 2 | X11 |
| A | 4 | X2 |
| A | 9 | Y4 |
| A | 11 | X1 |
| B | 3 | Y4 |
| B | 7 | X1 |
+----------+-----+------+
我想为每个客户创建一个具有“最新X类型”的列,如下所示:
+----------+-----+------+-------------+
| Customer | Day | Type | MostRecentX |
+----------+-----+------+-------------+
| A | 2 | X11 | X11 |
| A | 4 | X2 | X2 |
| A | 9 | Y4 | X2 |
| A | 11 | X1 | X1 |
| B | 3 | Y4 | - |
| B | 7 | X1 | X1 |
+----------+-----+------+-------------+
因此,对于X类型,它仅从当前行中获取一个,对于Y类型,则从该成员的最新X行中获取该类型(如果没有,则为空或东西)。我想我需要一种窗口功能,但对PySpark不太熟悉。
答案 0 :(得分:3)
您可以通过在last
列中将startswith
字母"X"
覆盖在Window
和{{1} {1}}。指定Customer
从分区的开头开始并在当前行停止。
Day
这里的技巧是仅在Window
开头的情况下使用when
返回from pyspark.sql import Window
from pyspark.sql.functions import col, last, when
w = Window.partitionBy("Customer").orderBy("Day").rowsBetween(Window.unboundedPreceding, 0)
df = df.withColumn(
"MostRecentX",
last(when(col("Type").startswith("X"), col("Type")), ignorenulls=True).over(w)
)
df.show()
#+--------+---+----+-----------+
#|Customer|Day|Type|MostRecentX|
#+--------+---+----+-----------+
#| A| 2| X11| X11|
#| A| 4| X2| X2|
#| A| 9| Y4| X2|
#| A| 11| X1| X1|
#| B| 3| Y4| null|
#| B| 7| X1| X1|
#+--------+---+----+-----------+
列。默认情况下,Type
将返回"X"
。然后我们可以将when
与null
一起使用,以获取last
的值。
如果您要按照问题所示将ignorenulls=True
替换为MostRecentX
,只需在null
列上调用"-"
:
fillna