新的火花,我正在学习。我有一个很大的文本文件,其列由“ |||||”分隔我想插入spark数据框。但是,该文件只是一个字符串。该文件如下所示:
col1|||||col2|||||col3|||||col4|||||col5|||||col1|||||col2|||||col3...
因此,第1列至第5列实际上只是在一行中循环。我尝试在每第5个“ |||||”之后插入新行通过以下命令使用sed命令:
sed -r 's/([^|||||]*|||||){5}/&\n/g'
哪个工作最多,但由于某种原因最终最终无法正常工作。我怀疑col4(这是一个巨大的文本字段)在此方面引起一些问题,但我对其执行原因的了解还不够。
现在,当我通过以下方式将单行文本文件读取到spark中时:
val df = spark.read.textFile(file)
这会将所有内容都放在一列中,我想将其分成5列,并让数据帧每5列“包装”字符串。
我的目标是将其变成这样:
+--------------------+---------------+--------------------+--------------------+--------------------+
| col1| col2| col3| col4| col5|
+--------------------+---------------+--------------------+--------------------+--------------------+
| val| val| val| val| val|
| val| val| val| val| val|
+--------------------+---------------+--------------------+--------------------+--------------------+
所以我的问题是:由于我的文件只是一个大字符串,是否有办法让数据框在5列之后输入新记录/行?
答案 0 :(得分:0)
这是您第一个问题的解决方案。 通常,您将其阅读为常规文本文件,然后使用split方法将行转换为列。
df.withColumn("tmp", split($"value", "|||||")).select(
$"tmp".getItem(0).as("first"),
$"tmp".getItem(1).as("second"),
$"tmp".getItem(2).as("third")
).drop("tmp")
第二个问题。您可以使用此正则表达式来匹配模式:
(([[a-z0-9A-Z] +)(\ | \ | \ || \ | \ ||)([a-z0-9A-Z] +)(\ | \ | \ || \\\\ |)([a-z0-9A-Z] +)(\ | \ | \ || \ | \ ||)([a-z0-9A-Z] +)(\ | \ | \\ | \\\\ |) )
如果有足够的内存,您可以读取所有文件,然后使用此模式提取文件的各个部分。
如果没有,则必须逐字节读取它,看看是否与该模式匹配。
祝你好运!
答案 1 :(得分:0)
如果文件很大,只有一行,则使用Perl解决方案。 Perl变量可以存储文件内容(甚至以GB为单位),并且您可以轻松管理。您可以在perl本身中进行所有预处理。看看下面的内容是否对您有用
Domain-Driven Design
将上面的输出重定向到另一个csv文件。现在,您可以将spark.csv作为5列的常规csv文件阅读