![](/img/trans.png)
[英]Converting a dataframe column with values to a list using spark and scala
[英]Iterate a column values in a Stream dataframe and assign each value to a common list using Scala and Spark
我有以下Stream Dataframe
+------------------------------------+
|______sentence______________________|
| Representative is a scientist |
| Norman did a good job in the exam |
| you want to go on shopping? |
--------------------------------------
我的清单如下
val myList
作为最终的 output 我需要 myList 在 stream dataframe 中包含以上三个句子
output
myList = [Representative is a scientist, Norman did a good job in the exam, you want to go on shopping? ]
我尝试了以下给出 stream 错误
val myList = sentenceDataframe.select("sentence").rdd.map(r => r(0)).collect.toList
上述方法抛出的错误
org.apache.spark.sql.AnalysisException:必须使用 writeStream.start() 执行带有流源的查询
请注意,上述方法适用于普通数据框,但不适用于 stream dataframe。
有没有办法遍历 stream dataframe 的每一行并使用scala 和 spark将行值分配到公共列表中?
这听起来像是一个非常奇怪的用例,因为 stream 理论上永远不会结束。 你确定你不只是在寻找常见的 spark DataFrames 吗?
如果不是这种情况,您可以做的是使用累加器和火花流 foreachBatch 接收器。 我使用了一个简单的套接字连接来演示这一点。 您可以使用 nc -lp 3030 在 ubuntu 下启动一个简单的套接字服务器,然后将消息传递给 stream,生成的 DataFrame 将具有 [值字符串] 的模式
val acc = spark.sparkContext.collectionAccumulator[String]
val stream = spark.readStream.format("socket").option("host", "localhost").option("port", "3030").load()
val query = stream.writeStream.foreachBatch((df: DataFrame, l: Long) => {
df.collect.foreach(v => acc.add(v(0).asInstanceOf[String]))
}).start()
...
// For some reason you are stopping the stream here
query.stop()
val myList = acc.value
现在你可能有一个问题是为什么我们使用累加器而不仅仅是一个 ArrayBuffer。 ArrayBuffers 可以在本地工作,但在集群上,foreachBatch 中的代码可能会在完全不同的节点上执行。 这意味着它不会有任何影响,这也是累加器首先存在的原因(参见https://spark.apache.org/docs/latest/rdd-programming-guide.html#accumulators )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.