Apache spark Spark窗口功能:为范围引用不同的列
我有一个数据框,其中列为Apache spark Spark窗口功能:为范围引用不同的列,apache-spark,pyspark,spark-dataframe,window-functions,pyspark-sql,Apache Spark,Pyspark,Spark Dataframe,Window Functions,Pyspark Sql,我有一个数据框,其中列为start\u time和end\u time。我想设置窗口,每个观察的窗口在结束时间之前是它前面的两行,限制为在该观察的开始时间之前有一个end\u时间的数据 示例数据: data = [('a', 10, 12, 5),('b', 20, 25, 10),('c', 30, 60, 15),('d', 40, 45, 20),('e', 50, 70, 25)] df = sqlContext.createDataFrame(data, ['name', 'start
start\u time
和end\u time
。我想设置窗口,每个观察的窗口在结束时间之前是它前面的两行,限制为在该观察的开始时间之前有一个end\u时间的数据
示例数据:
data = [('a', 10, 12, 5),('b', 20, 25, 10),('c', 30, 60, 15),('d', 40, 45, 20),('e', 50, 70, 25)]
df = sqlContext.createDataFrame(data, ['name', 'start_time', 'end_time', 'resource'])
+----+----------+--------+--------+
|name|start_time|end_time|resource|
+----+----------+--------+--------+
| a| 10| 12| 5|
| b| 20| 25| 10|
| c| 30| 60| 15|
| d| 40| 45| 20|
| e| 50| 70| 25|
+----+----------+--------+--------+
因此,“e”的窗口应该包括“b”和“d”,而不是“c”
没有结束时间<开始时间的限制,我可以使用
from pyspark.sql import Window
from pyspark.sql import functions as func
window = Window.orderBy("name").rowsBetween(-2, -1)
df.select('*', func.avg("resource").over(window).alias("avg")).show()
我查看了rangeBetween()
,但我找不到引用当前行的start\u time
的方法,或者我想通过其他行的end\u time
来限制它。有Window.currentRow
,但在本例中,它只会引用resource
这可以使用Windows来完成吗?我应该完全尝试别的吗
编辑:如果有必要,可以使用Spark 2.1.1和Python 2.7+。您实际上可以使用groupBy函数对不同分区进行聚合,然后在同一公共键上使用输出数据帧之间的内部联接。Partition by或window函数在spark中需要花费大量时间,因此如果可以,最好使用groupby。您实际上可以使用groupby函数对不同的分区进行聚合,然后通过相同的公共键使用输出数据帧之间的内部联接。分区依据或窗口函数在spark中需要花费大量时间,因此如果可以,最好使用groupby。我认为纯粹使用windows是不可能的。从给定的行开始,您需要能够按照与前面的行相反的排序顺序工作,直到有两个满足条件的点击
您可以使用一个窗口函数来创建一个列表,其中列出了每一行之前遇到的所有值,然后使用一个带有纯scala/python的UDF来确定总和,从而说明排除情况
在scala中:
val window = Window.partitionBy(???).orderBy("end_time").rowsBetween(Long.MinValue, -1)
val udfWithSelectionLogic = udf { values: Seq[Row] => INSERT_LOGIC_HERE_TO_CALCULATE_AGGREGATE }
val dataPlus = data.withColumn("combined", struct($"start_time", $"end_time", $"resource"))
.withColumn("collected", collect_list($"combined") over window)
.withColumn("result", udfWithSelectionLogic($"collected"))
这并不理想,但可能会有所帮助。我认为纯粹使用windows不可能做到这一点。从给定的行开始,您需要能够按照与前面的行相反的排序顺序工作,直到有两个满足条件的点击
您可以使用一个窗口函数来创建一个列表,其中列出了每一行之前遇到的所有值,然后使用一个带有纯scala/python的UDF来确定总和,从而说明排除情况
在scala中:
val window = Window.partitionBy(???).orderBy("end_time").rowsBetween(Long.MinValue, -1)
val udfWithSelectionLogic = udf { values: Seq[Row] => INSERT_LOGIC_HERE_TO_CALCULATE_AGGREGATE }
val dataPlus = data.withColumn("combined", struct($"start_time", $"end_time", $"resource"))
.withColumn("collected", collect_list($"combined") over window)
.withColumn("result", udfWithSelectionLogic($"collected"))
这并不理想,但可能会有所帮助。分区依据是什么?没有它,所有的行都会在同一个分区中,在一个执行器上,这会用大数据集杀死它。是的,我的实际数据非常大,所以我有一个partitionBy
,它似乎工作得很好-name
的组,每个组都有一个a,b,c,等等。当我运行代码时,没有只考虑结束时间<当前行开始时间的数据的限制,它似乎没有任何问题。我只是在集成此限制时遇到问题。分区依据是什么?没有它,所有的行都会在同一个分区中,在一个执行器上,这会用大数据集杀死它。是的,我的实际数据非常大,所以我有一个partitionBy
,它似乎工作得很好-name
的组,每个组都有一个a,b,c,等等。当我运行代码时,没有只考虑结束时间<当前行开始时间的数据的限制,它似乎没有任何问题。我只是在整合这个限制时遇到了问题。