我在pyspark中有一个数据框
id | value
1 0
1 1
1 0
2 1
2 0
3 0
3 0
3 1
我想提取同一id组中value列中第一次出现1之后的所有行。我已经创建了带有ID分区的Window,但是不知道如何获取值1之后的行。
我希望结果是
id | value
1 1
1 0
2 1
2 0
3 1
答案 0 :(得分:1)
以下解决方案可能与此有关(对于小数据来说,它工作得很好,但如果id
在多个分区上,则可能在大数据中引起问题)
df = sqlContext.createDataFrame([
[1, 0],
[1, 1],
[1, 0],
[2, 1],
[2, 0],
[3, 0],
[3, 0],
[3, 1]
],
['id', 'Value']
)
df.show()
+---+-----+
| id|Value|
+---+-----+
| 1| 0|
| 1| 1|
| 1| 0|
| 2| 1|
| 2| 0|
| 3| 0|
| 3| 0|
| 3| 1|
+---+-----+
#importing Libraries
from pyspark.sql import functions as F
from pyspark.sql.window import Window as W
import sys
#This way we can generate a cumulative sum for values
df.withColumn(
"sum",
F.sum(
"value"
).over(W.partitionBy(["id"]).rowsBetween(-sys.maxsize, 0))
).show()
+---+-----+-----+
| id|Value|sum |
+---+-----+-----+
| 1| 0| 0|
| 1| 1| 1|
| 1| 0| 1|
| 3| 0| 0|
| 3| 0| 0|
| 3| 1| 1|
| 2| 1| 1|
| 2| 0| 1|
+---+-----+-----+
#Filter all those which are having sum > 0
df.withColumn(
"sum",
F.sum(
"value"
).over(W.partitionBy(["id"]).rowsBetween(-sys.maxsize, 0))
).where("sum > 0").show()
+---+-----+-----+
| id|Value|sum |
+---+-----+-----+
| 1| 1| 1|
| 1| 0| 1|
| 3| 1| 1|
| 2| 1| 1|
| 2| 0| 1|
+---+-----+-----+
在运行此命令之前,必须确保与ID相关的数据应进行分区,并且ID不能位于2个分区上。
答案 1 :(得分:0)
理想情况下,您需要:
id
分区的窗口,并按照数据框已经存在的相同顺序进行排序AFAIK,Spark的Windows中没有查找功能。但是,您可以遵循这个想法并做出一些努力。首先创建数据并导入函数和窗口。
import pyspark.sql.functions as F
from pyspark.sql.window import Window
l = [(1, 0), (1, 1), (1, 0), (2, 1), (2, 0), (3, 0), (3, 0), (3, 1)]
df = spark.createDataFrame(l, ['id', 'value'])
然后,让我们在数据框上添加一个索引(它是免费的)以便能够订购窗口。
indexedDf = df.withColumn("index", F.monotonically_increasing_id())
然后,我们创建一个窗口,该窗口仅查看当前行之前的值,并按该索引排序并按ID进行分区。
w = Window.partitionBy("id").orderBy("index").rowsBetween(Window.unboundedPreceding, 0)
最后,我们使用该窗口来收集每行的一组先前值,并过滤掉不包含1
的那些值。 (可选)我们以index
的顺序退货,因为窗口不保留id
列的订单。
indexedDf\
.withColumn('set', F.collect_set(F.col('value')).over(w))\
.where(F.array_contains(F.col('set'), 1))\
.orderBy("index")\
.select("id", "value").show()
+---+-----+
| id|value|
+---+-----+
| 1| 1|
| 1| 0|
| 2| 1|
| 2| 0|
| 3| 1|
+---+-----+