如何从半结构化文本文件加载DataFrame?

时间:2018-04-15 18:41:48

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

我有一个半结构化的文本文件,我想将它转换为Spark中的数据框。我心里有一个架构,如下所示。但是,我发现解析我的文本文件并分配模式很有挑战性。

以下是我的示例文本文件:

    "good service"
    Tom Martin (USA) 17th October 2015    
    4    
    Long review..    
    Type Of Traveller   Couple Leisure    
    Cabin Flown Economy    
    Route   Miami to Chicago    
    Date Flown  September 2015    
    Seat Comfort    12345    
    Cabin Staff Service 12345    
    Ground Service  12345    
    Value For Money 12345    
    Recommended no

    "not bad"
    M Muller (Canada) 22nd September 2015
    6
    Yet another long review..
    Aircraft    TXT-101
    Type Of Customer    Couple Leisure
    Cabin Flown FirstClass
    Route   IND to CHI
    Date Flown  September 2015
    Seat Comfort    12345
    Cabin Staff Service 12345
    Food & Beverages    12345
    Inflight Entertainment  12345
    Ground Service  12345
    Value For Money 12345
    Recommended yes

.
.

结果模式的结果我希望如下:

+----------------+------------+--------------+---------------------+---------------+---------------------------+----------+------------------+-------------+--------------+-------------------+----------------+--------------+---------------------+-----------------+------------------------+----------------+---------------------+-----------------+
| Review_Header  | User_Name  | User_Country |  User_Review_Date   | Overall Score |          Review           | Aircraft | Type of Traveler | Cabin Flown | Route_Source | Route_Destination |   Date Flown   | Seat Comfort | Cabin Staff Service | Food & Beverage | Inflight Entertainment | Ground Service | Wifi & Connectivity | Value for Money |
+----------------+------------+--------------+---------------------+---------------+---------------------------+----------+------------------+-------------+--------------+-------------------+----------------+--------------+---------------------+-----------------+------------------------+----------------+---------------------+-----------------+
| "good service" | Tom Martin | USA          | 17th October 2015   |             4 | Long review..             |          | Couple Leisure   | Economy     | Miami        | Chicago           | September 2015 |        12345 |               12345 |                 |                        |          12345 |                     |           12345 |
| "not bad"      | M Muller   | Canada       | 22nd September 2015 |             6 | Yet another long review.. | TXT-101  | Couple Leisure   | FirstClass  | IND          | CHI               | September 2015 |        12345 |               12345 |           12345 |                  12345 |          12345 |                     |           12345 |
+----------------+------------+--------------+---------------------+---------------+---------------------------+----------+------------------+-------------+--------------+-------------------+----------------+--------------+---------------------+-----------------+------------------------+----------------+---------------------+-----------------+

您可能会注意到,对于文本文件中的每个数据块,前四行都映射到用户定义的列,例如Review_Header,User_Name,User_Country,User_Review_Date,而其他各行已定义列。

在这种情况下使用schema inference technique而不是编写详细代码的最佳方法是什么?

更新:我想让这个问题变得更棘手。如果" Long评论怎么办?"和#34;又一个长期评论"本身可以跨越多个换行符。我如何解析每个块的多行评论?

2 个答案:

答案 0 :(得分:3)

如果您保证半结构化文本文件的记录由两个换行符分隔,并且这两个换行符永远不会出现在“Long review ...”部分中,您可以使用带有修改分隔符的textFiles ("\n\n")然后处理这些行而不编写自定义文件格式。

sc.hadoopConfiguration.set("textinputformat.record.delimiter", "\n\n")
df = sc.textFile("sample-file.txt")

然后,您可以在"\n""\t"上进一步分割,以创建字段和列。

看到你的更新,这是一个很难的问题。您必须问自己,在评论中没有的属性中有哪些识别信息。或者保证以特定格式保证。 E.g。

  • 您能否保证长篇评论中没有两个换行符?如果我们拆分"\n\n"来生成块,这很重要。
  • 你能保证长篇评论中没有标签吗?
  • Aircraft, Cabin Flown, Cabin Staff Service, Date Flown, Food & Beverages, Ground Service, ...是完整的属性列表吗?你有完整的可能属性列表吗?

以及一些元问题:

  • 这些数据来自哪里?
  • 我们能以更好的格式请求吗?
  • 我们能从更好的来源找到这些数据或我们正在寻找的方面吗?

有了这些知识,你就可以更好地了解如何继续。例如。如果评论文本中没有标签,(或者它们被转义为“\ t”或其他内容):

  • 提取lines[0] - 第一行“良好服务”
  • 提取lines[1] - 拆分为用户名,国家/地区,审核日期
  • 过滤包含标签的lines[2:],获取最低索引i - 拆分为属性
  • 使用lines[2:i]加入"\n" - 这是审核

答案 1 :(得分:0)

  

在这种情况下使用模式推理技术而不是编写详细代码的最佳方法是什么?

您没有太多选择,您必须编写详细代码或自定义FileFormat(这会隐藏将此类文件加载到DataFrame的复杂性。)

使用DataFrameReader.textFile加载文件并相应地对其进行转换。

  

textFile(path:String):Dataset [String] 加载文本文件并返回String的数据集。有关更多详细信息,请参阅其他重载的textFile()方法的文档。