2

我试图通过使用窗口函数来确定 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'))

没有错误。不幸的是,这不是我当前设置的选项。

4

1 回答 1

1

它看起来像 Catalyst 中的一个错误,但是。链接方法应该可以正常工作:

df.select(diff.alias('diff')).agg(functions.avg('diff'))

不过,我会在这里小心。不应使用窗口函数来执行全局(无PARTITION BY子句)操作。这些将所有数据移动到单个分区并执行顺序扫描。在这里使用 RDD 可能是更好的选择。

于 2016-01-14T18:26:14.067 回答