将每个文件都标记为数据集行

时间:2017-01-27 16:04:29

标签: scala apache-spark apache-spark-sql

我在目录中有很多文件,每个文件包含跨越多行的文本。 目前,我使用以下代码将所有这些文件读取到spark数据集(> 2.0)

   val ddf = spark.read.text("file:///input/*")

但是,这会创建一个数据集,其中每行都是一行,而不是文件。我想在数据集中的每一行中包含每个文件(作为字符串)。

如何在不迭代每个文件并单独阅读RDD的情况下实现此目的?

2 个答案:

答案 0 :(得分:4)

wholeTextFiles()

上使用SparkContext
val rdd: RDD[(String, String)] = spark.sparkContext
                                      .wholeTextFiles("file/path/to/read/as/rdd")
  

SparkContext.wholeTextFiles 可让您阅读包含的目录   多个小文本文件,并将每个文件作为返回(文件名,   内容)对。这与textFile相反,后者将返回   每个文件中每行一条记录。

答案 1 :(得分:2)

@ mrsrinivas答案的替代方法是按input_file_name分组。鉴于结构:

evan@vbox>~/junk/so> find .        
.
./d2
./d2/t.txt
./d1
./d1/t.txt
 evan@vbox>~/junk/so> cat  */*.txt
d1_1
d1_2
d2_1
d2_2

我们可以根据输入文件收集列表,如下所示:

scala> val ddf = spark.read.textFile("file:///home/evan/junk/so/*").
     | select($"value", input_file_name as "fName")
ddf: org.apache.spark.sql.DataFrame = [value: string, fName: string]

scala> ddf.show(false)
+-----+----------------------------------+
|value|fName                             |
+-----+----------------------------------+
|d2_1 |file:///home/evan/junk/so/d2/t.txt|
|d2_2 |file:///home/evan/junk/so/d2/t.txt|
|d1_1 |file:///home/evan/junk/so/d1/t.txt|
|d1_2 |file:///home/evan/junk/so/d1/t.txt|
+-----+----------------------------------+

scala> ddf.groupBy("fName").agg(collect_list($"value") as "value").
     | drop("fName").show
+------------+
|       value|
+------------+
|[d1_1, d1_2]|
|[d2_1, d2_2]|
+------------+