【问题标题】:How to iterate records spark scala?如何迭代记录火花scala?
【发布时间】:2015-10-09 05:45:37
【问题描述】:

我有一个变量“myrdd”,它是一个 avro 文件,其中包含通过 hadoopfile 加载的 10 条记录。

当我这样做时

myrdd.first_1.datum.getName()

我可以知道名字。问题是,我在“myrdd”中有 10 条记录。当我这样做时:

myrdd.map(x => {println(x._1.datum.getName())})

它不起作用,并且一次打印出一个奇怪的对象。如何遍历所有记录?

【问题讨论】:

  • 问题需要示例。它应该涵盖 avro 数据和有问题的输出。

标签: scala apache-spark avro


【解决方案1】:

这是来自使用spark-shell 的会话的日志,具有类似的场景。

给定

scala> persons
res8: org.apache.spark.sql.DataFrame = [name: string, age: int]

scala> persons.first
res7: org.apache.spark.sql.Row = [Justin,19]

你的问题看起来像

scala> persons.map(t => println(t))
res4: org.apache.spark.rdd.RDD[Unit] = MapPartitionsRDD[10]

所以map 只是返回另一个RDD(该函数不会立即应用,当您真正迭代结果时,该函数会“延迟”应用)。

所以当你实现(使用collect())你会得到一个“正常”的集合:

scala> persons.collect()
res11: Array[org.apache.spark.sql.Row] = Array([Justin,19])

你可以map。请注意,在这种情况下,您在传递给mapprintln)的闭包中有副作用,println 的结果是Unit):

scala> persons.collect().map(t => println(t))
[Justin,19]
res5: Array[Unit] = Array(())

如果最后应用collect,结果相同:

scala> persons.map(t => println(t)).collect()
[Justin,19]
res19: Array[Unit] = Array(())

但如果您只想打印行,您可以将其简化为使用foreach

scala> persons.foreach(t => println(t))
[Justin,19]

正如@RohanAletty 在评论中指出的那样,这适用于本地 Spark 作业。如果作业在集群中运行,collect 也是必需的:

persons.collect().foreach(t => println(t))

注意事项

  • Iterator 类中可以观察到相同的行为。
  • 上述会话的输出已重新排序

更新

关于过滤:collect的位置是“坏”的,如果你在collect之后应用过滤器,可以在之前应用。

例如,这些表达式给出相同的结果:

scala> persons.filter("age > 20").collect().foreach(println)
[Michael,29]
[Andy,30]

scala> persons.collect().filter(r => r.getInt(1) >= 20).foreach(println)
[Michael,29]
[Andy,30]

但第二种情况更糟,因为该过滤器可能在 collect 之前应用。

这同样适用于任何类型的聚合。

【讨论】:

  • 请注意:如果这是在集群上运行,您需要在 RDD 上使用take()collect(),然后再调用foreach(println)。这是因为,由于 spark 上下文在那里运行,因此必须将数据带回驱动程序。 (对于本地火花计划,您的答案很好。)
  • 如果我有一百万条记录,我听说收集不好,因为所有数据都发送到你的机器......有没有办法让它说,我可以“预过滤”所有在执行 foreach(println) 之前是“贾斯汀”和 18/19 岁的名字?基本上,如果我有一个 5 节点集群,我想在循环通过我想要输出的剩余记录之前在所有机器之间“划分”预过滤工作。
  • @Rolando 请查看更新后的答案 - 我在collect 的“两侧”添加了一个带有过滤器的示例。
  • @RohanAletty 感谢您的提示;我已经更新了答案
猜你喜欢
  • 1970-01-01
  • 2017-04-12
  • 2016-04-22
  • 1970-01-01
  • 1970-01-01
  • 2017-06-19
  • 1970-01-01
  • 2017-03-29
  • 2018-12-23
相关资源
最近更新 更多