如何在Pyspark中以编程方式解析固定宽度的文本文件?

时间:2017-09-08 14:16:21

标签: apache-spark pyspark spark-dataframe

这篇文章很好地展示了如何使用pyspark(pyspark parse text file)将固定宽度的文本文件解析为Spark数据帧。

我有几个我要解析的文本文件,但它们各自的模式略有不同。我不想像上一篇文章那样为每一个写出相同的程序,而是想编写一个通用函数,它可以解析宽度和列名称的固定宽度文本文件。

我对pyspark很新,所以我不知道如何编写一个select语句,其中列数及其类型是可变的。

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:3)

假设我们有一个类似示例线程中的文本文件:

00101292017you1234
00201302017 me5678
"/tmp/sample.txt"中的

。以及包含每个文件名,列列表和宽度列表的字典:

schema_dict = {
    "sample": {
        "columns": ["id", "date", "string", "integer"], 
        "width" : [3, 8, 3, 4]
    }
}

我们可以加载数据帧并使用以下方法迭代地将它们拆分成列:

import numpy as np

input_path = "/tmp/"
df_dict = dict()
for file in schema_dict.keys():
    df = spark.read.text(input_path + file + ".txt")
    start_list = np.cumsum([1] + schema_dict[file]["width"]).tolist()[:-1]
    df_dict[file] = df.select(
        [
            df.value.substr(
                start_list[i], 
                schema_dict[file]["width"][i]
            ).alias(schema_dict[file]["columns"][i]) for i in range(len(start_list))
        ]
    )

    +---+--------+------+-------+
    | id|    date|string|integer|
    +---+--------+------+-------+
    |001|01292017|   you|   1234|
    |002|01302017|    me|   5678|
    +---+--------+------+-------+