从文件scala

时间:2018-03-27 12:35:40

标签: scala apache-spark text-files

我正在使用scala玩一点,我想打开一个文本文件,读取每一行并保存一些hashset中的字段。 输入文件将是这样的:

1 2 3
2 4 5

首先,我只是想将每列的第一个元素存储到一个变量中,但似乎没有任何事情发生。 我的代码是:

var id = 0
val textFile = sc.textFile(inputFile);
val nline = textFile.map(_.split(" ")).foreach(r => id = r(0))

我正在使用spark因为我想稍后处理更大量的数据,所以我试图习惯它。我正在打印id,但我只得到0   有什么想法吗?

2 个答案:

答案 0 :(得分:1)

有几件事:

首先,在map和foreach中,您正在执行代码上运行代码。您定义的id变量位于驱动程序上。您可以使用闭包将变量传递给执行程序,但不是相反。如果您考虑一下,当您有10个执行者同时运行记录时,您希望返回哪个ID值?

编辑 - foreach是一项操作

我错误地称foreach不是下面的动作。这是一个只允许您对行运行任意代码的操作。例如,如果您有自己的代码将结果保存到其他数据存储,则非常有用。 foreach不会将任何数据带回给驱动程序,因此对您的情况没有帮助。

结束修改

其次,你调用的所有spark方法都是转换,你还没有调用一个动作。在调用动作之前,Spark实际上并不运行任何代码。相反,它只是在您指定操作之前构建要发生的转换的图形。操作是需要实现结果的东西,要么将数据提供给驱动程序,要么将它们保存在HDFS之类的某个地方。

在你的情况下,为了获得价值,你会想要使用像"收集"它将RDD中的所有值返回给驱动程序。但是,只有当您知道返回的值不是很多时,才应该这样做。如果你在1亿条记录上运行,你不想尝试将它们全部拉回给驱动程序!一般来说,您只需要在处理并减少数据后将数据拉回驱动程序。

答案 1 :(得分:0)

  

我只是想将每列的第一个元素存储到a   变量似乎没有发生。

val file_path = "file.txt"
val ds = ss.read.textFile(file_path)

val ar = ds.map(x => x.split(" ")).first()
val (x,y,z) = (ar(0),ar(1),ar(2))

您可以使用上面的x,y,z访问列的第一个值。 使用您的文件,x = 1,y = 2,z = 3。

val ar1 = ds.map(x => x.split(" "))
val final_ds = ar.select($"value".getItem(0).as("col1") , $"value".getItem(1).as("col2") , $"value".getItem(2).as("col3")) // you can name the columns as like this

Output :
+----+----+----+
|col1|col2|col3|
+----+----+----+
|   1|   2|   3|
|   2|   4|   5|
+----+----+----+

您可以在final_ds上运行任何类型的sql,就像下面的小样本一样。

final_ds.select("col1","col2").where(final_ds.col("col1") > 1).show()

Output:
+----+----+
|col1|col2|
+----+----+
|   2|   4|
+----+----+