Spark DataFrame中布局TimeSeries数据的最佳方法 - Scala

时间:2017-01-24 03:14:01

标签: json scala apache-spark time-series spark-dataframe

我从美联储经济数据集API导入数据。每个请求都会返回每日,每周,每月或每年的时间序列。我的最终目标是进行变量选择并构建基于贝叶斯的模型,该模型使用所选时间序列作为特定时间序列的预测变量。将此数据构建到数据框架的最佳方法是什么?

根据这个documentation,我认为我的数据应该在“Instants”format中列出。然而,在尝试加入超过200,000列的数据之后,我的尝试最终都变得非常缓慢。下面文档参考中的另一种格式是“TimeSeriesRDD”,但导入的时间序列通常没有日期重叠,范围从1930年到现在。那么,将这些数据构建到数据框架的最佳方法是什么?

如何将FRED数据加载到推荐格式的示例将非常感谢!

这是我的第一种非常慢的方法

for (seriesId <- allSeries) {
    val series = loadSeriesFromAPI(seriesId, spark)
    allSeries = allSeries.join(series, allSeries.col("date") === series.col(seriesId + "_date"), "outer")
    allSeries = allSeries.drop(seriesId + "_date")
}

我的第二个,我必须一次加载数据1列和1行

for(row <- series) {
  val insertStr = "%s, %g".
    format(
      row.asInstanceOf[Map[String, Date]]("date").asInstanceOf[String],
      parseDoubleOrZero(row.asInstanceOf[Map[String, Double]]("value").asInstanceOf[String])
    )
}

1 个答案:

答案 0 :(得分:3)

拥有200.000列的DataFrame不是一个好主意。我建议的一件事是在不混合太多技术的情况下将问题分开一点:

  1. 数据摄取:你的系列实际有多大?尽可能避免连接(连接意味着改组,改组意味着网络,这将使一切变慢)。我会用Scala收集数据并将其保存在内存中(如果不适合),如果没有,我仍然会在Scala中收集批量系列并在Spark DataFrame中转换每个批次。
  2. 数据框创建:如果您设法将数据存储在内存中,那么您可以尝试使用以下代码片段来创建数据框:
  3. case class Point(timestamp: Long, value: Long)
    case class Series(id: String, points: List[Point])
    
    val s1 = Series("s1", List(Point(1, 100), Point(2, 200), Point(3, 100)))
    val s2 = Series("s2", List(Point(1, 1000), Point(3, 100)))
    
    val seriesDF = sc.parallelize(Array(s1, s2)).toDF
    seriesDF.show()
    
    seriesDF.select($"id", explode($"points").as("point"))
        .select($"id", $"point.timestamp", $"point.value")
        .show()
    

    输出:

    +---+--------------------+
    | id|              points|
    +---+--------------------+
    | s1|[[1,100], [2,200]...|
    | s2| [[1,1000], [3,100]]|
    +---+--------------------+
    +---+---------+-----+
    | id|timestamp|value|
    +---+---------+-----+
    | s1|        1|  100|
    | s1|        2|  200|
    | s1|        3|  100|
    | s2|        1| 1000|
    | s2|        3|  100|
    +---+---------+-----+
    

    对于处理时间序列的更奇特的方法,我建议使用以下项目:https://github.com/twosigma/flint