[英]Read fixed width file using schema from json file in pyspark
我有如下固定寬度的文件
00120181120xyz12341
00220180203abc56792
00320181203pqr25483
以及指定架構的相應JSON
文件:
{"Column":"id","From":"1","To":"3"}
{"Column":"date","From":"4","To":"8"}
{"Column":"name","From":"12","To":"3"}
{"Column":"salary","From":"15","To":"5"}
我使用以下方法將架構文件讀入 DataFrame:
SchemaFile = spark.read\
.format("json")\
.option("header","true")\
.json('C:\Temp\schemaFile\schema.json')
SchemaFile.show()
#+------+----+---+
#|Column|From| To|
#+------+----+---+
#| id| 1| 3|
#| date| 4| 8|
#| name| 12| 3|
#|salary| 15| 5|
#+------+----+---+
同樣,我將固定寬度文件解析為 pyspark DataFrame,如下所示:
File = spark.read\
.format("csv")\
.option("header","false")\
.load("C:\Temp\samplefile.txt")
File.show()
#+-------------------+
#| _c0|
#+-------------------+
#|00120181120xyz12341|
#|00220180203abc56792|
#|00320181203pqr25483|
#+-------------------+
我顯然可以對每列的位置和長度的值進行硬編碼以獲得所需的輸出:
from pyspark.sql.functions import substring
data = File.select(
substring(File._c0,1,3).alias('id'),
substring(File._c0,4,8).alias('date'),
substring(File._c0,12,3).alias('name'),
substring(File._c0,15,5).alias('salary')
)
data.show()
#+---+--------+----+------+
#| id| date|name|salary|
#+---+--------+----+------+
#|001|20181120| xyz| 12341|
#|002|20180203| abc| 56792|
#|003|20181203| pqr| 25483|
#+---+--------+----+------+
但是我如何使用SchemaFile
DataFrame 來指定行的寬度和列名,以便可以在運行時動態應用模式(無需硬編碼)?
此處最簡單的做法是collect
SchemaFile
的內容並遍歷其行以提取所需數據。
首先將架構文件作為 JSON 讀取到 DataFrame 中。 然后調用 collect 並將每一行映射到字典:
sfDict = map(lambda x: x.asDict(), SchemaFile.collect())
print(sfDict)
#[{'Column': u'id', 'From': u'1', 'To': u'3'},
# {'Column': u'date', 'From': u'4', 'To': u'8'},
# {'Column': u'name', 'From': u'12', 'To': u'3'},
# {'Column': u'salary', 'From': u'15', 'To': u'5'}]
現在您可以遍歷sfDict
中的行並使用這些值來對您的列進行子字符串化:
from pyspark.sql.functions import substring
File.select(
*[
substring(
str='_c0',
pos=int(row['From']),
len=int(row['To'])
).alias(row['Column'])
for row in sfDict
]
).show()
#+---+--------+----+------+
#| id| date|name|salary|
#+---+--------+----+------+
#|001|20181120| xyz| 12341|
#|002|20180203| abc| 56792|
#|003|20181203| pqr| 25483|
#+---+--------+----+------+
請注意,我們必須將To
和From
轉換為整數,因為它們在您的json
文件中被指定為字符串。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.