首页 > 解决方案 > Spark写入输出为固定宽度

问题描述

将固定宽度的文件读入 Spark 很容易,并且有多种方法可以做到这一点。但是,我找不到从 spark (2.3.1) 写入固定宽度输出的方法。将 DF 转换为 RDD 有帮助吗?目前使用 Pyspark,但欢迎使用任何语言。有人可以建议出路吗?

标签: apache-sparkpysparkapache-spark-sqlfixed-width

解决方案


这是我在评论中描述的一个例子。

您可以使用pyspark.sql.functions.format_string()将每列格式化为固定宽度,然后pyspark.sql.functions.concat()将它们全部组合成一个字符串。

例如,假设您有以下 DataFrame:

data = [
    (1, "one", "2016-01-01"),
    (2, "two", "2016-02-01"),
    (3, "three", "2016-03-01")
]

df = spark.createDataFrame(data, ["id", "value", "date"])
df.show()
#+---+-----+----------+
#| id|value|      date|
#+---+-----+----------+
#|  1|  one|2016-01-01|
#|  2|  two|2016-02-01|
#|  3|three|2016-03-01|
#+---+-----+----------+

假设您想写出数据左对齐,固定宽度为 10

from pyspark.sql.functions import concat, format_string

fixed_width = 10
ljust = r"%-{width}s".format(width=fixed_width)

df.select(
    concat(*[format_string(ljust,c) for c in df.columns]).alias("fixedWidth")
).show(truncate=False)
#+------------------------------+
#|fixedWidth                    |
#+------------------------------+
#|1         one       2016-01-01|
#|2         two       2016-02-01|
#|3         three     2016-03-01|
#+------------------------------+

这里我们使用printf样式格式%-10s来指定左对齐宽度 10。

相反,如果您想右对齐字符串,请删除负号:

rjust = r"%{width}s".format(width=fixed_width)

df.select(
    concat(*[format_string(rjust,c) for c in df.columns]).alias("fixedWidth")
).show(truncate=False)
#+------------------------------+
#|fixedWidth                    |
#+------------------------------+
#|         1       one2016-01-01|
#|         2       two2016-02-01|
#|         3     three2016-03-01|
#+------------------------------+

现在您可以只将fixedWidth列写入输出文件。


推荐阅读