我试图通过使用窗口函数来确定Dataframe列中日期之间的平均时间跨度。然而,实现Dataframe会引发Java异常。
考虑以下示例:
from pyspark import SparkContext
from pyspark.sql import HiveContext, Window, functions
from datetime import datetime
sc = SparkContext()
sq = HiveContext(sc)
data = [
[datetime(2014,1,1)],
[datetime(2014,2,1)],
[datetime(2014,3,1)],
[datetime(2014,3,6)],
[datetime(2014,8,23)],
[datetime(2014,10,1)],
]
df = sq.createDataFrame(data, schema=['ts'])
ts = functions.col('ts')
w = Window.orderBy(ts)
diff = functions.datediff(
ts,
functions.lag(ts, count=1).over(w)
)
avg_diff = functions.avg(diff)
df.select(diff.alias('diff')).show()
正确呈现为
+----+
|diff|
+----+
|null|
| 31|
| 28|
| 5|
| 170|
| 39|
+----+
执行df.select(avg_diff).show()
会得到java.lang.StackOverflowError
。
我认为这应该有用吗?如果是这样,我做错了什么,我该怎么办呢?
我在Spark 1.6上使用Python API
当我执行df2 = df.select(diff.alias('diff'))
然后执行
df2.select(functions.avg('diff'))
没有错误。不幸的是,这不是我当前设置中的一个选项。
答案 0 :(得分:1)
它看起来像Catalyst中的一个错误但是。链接方法应该可以正常工作:
df.select(diff.alias('diff')).agg(functions.avg('diff'))
不过我在这里要小心。不应使用窗口函数来执行全局(没有PARTITION BY
子句)操作。这些将所有数据移动到单个分区并执行顺序扫描。在这里使用RDD可能是更好的选择。