[英]Filtering trash from a JSON file before reading it into PySpark DataFrame
我有以下文件,該文件應該是JSON文件,但是在實際的JSON內容(它們之間用制表符分隔!)之前有一個字符串。
string_smth\t{id:"str", num:0}
string_smth1\t{id:"str2", num:1}
string_smth2\t{id:"str3", num:2}
string_smth3\t{id:"str4", num:3}
執行以下操作將為所有列返回空值:
import pyspark.sql
from pyspark.sql.types import *
schema = StructType([
StructField("id", StringType()),
StructField("num", IntegerType())
])
df = spark.read.json("hdfs:///path/files.json/*", schema=schema)
df.show()
+--+---+
|id|num|
+--+---+
|null|null|
|null|null|
|null|null|
|null|null|
有什么方法可以在spark.read.json
調用中解決此問題? 如果沒有,我有什么選擇?
我可以在您的文件中看到幾個問題,但是也許這只是與您的示例相關的問題。
我創建了一個rdd:
a = sc.parallelize(['string_smth\t{"id":"str","num":0}',
'string_smth1\t{"id":"str2","num":1}',
'string_smth2\t{"id":"str3","num":2}',
'string_smth3\t{"id":"str4","num":3}'])
在您的情況下,將此sc.parallelize
替換為sc.textFile(path_to_file)
即可獲取所需的文件。 如您所見,該id
用雙引號引起來。 這就是json應該采用字符串格式的方式。 而且,從技術上講,逗號后沒有空格。 您的原始文件到底如何?
然后,只需執行以下操作:
import json
schema = StructType([
StructField("id", StringType()),
StructField("num", IntegerType())
])
a.map(lambda x : json.loads(x.split('\t')[1])).toDF(schema).show()
+----+---+
| id|num|
+----+---+
| str| 0|
|str2| 1|
|str3| 2|
|str4| 3|
+----+---+
json,struct和case類不需要創建架構。
您可以使用sparkContext
的textFile
api讀取文本文件並解析行以獲取有效的json字符串
rdd = sc.textFile("path to the csv file")\
.map(lambda line: line.split("\t", 1)[1].replace("id:", "\"id\":").replace("num:", "\"num\":"))
后來終於轉換成有效的JSON RDDS到dataframe
df = sqlContext.read.json(rdd)
這應該給你
+----+---+
|id |num|
+----+---+
|str |0 |
|str2|1 |
|str3|2 |
|str4|3 |
+----+---+
一個可能的解決方案是在每行的'{'字符上分割:
json_lin = '{' + 'string_smth {id:"str", num:0}'.split('{')[-1]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.