Python 在将JSON文件读入PySpark数据帧之前过滤JSON文件中的垃圾

Python 在将JSON文件读入PySpark数据帧之前过滤JSON文件中的垃圾,python,apache-spark,pyspark,Python,Apache Spark,Pyspark,我有以下文件,它应该是一个JSON文件,但它在实际JSON内容之前有一个字符串(它们由一个选项卡分隔!): 执行以下操作将为所有列返回null: import pyspark.sql from pyspark.sql.types import * schema = StructType([ StructField("id", StringType()), StructField("num", IntegerType()) ]) df = spark.read.js

我有以下文件,它应该是一个JSON文件,但它在实际JSON内容之前有一个字符串(它们由一个选项卡分隔!):

执行以下操作将为所有列返回null:

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
调用期间,有没有办法解决这个问题?如果没有,我的选择是什么?

一个可能的解决方案是在每行的“{”字符上拆分:

json_lin = '{' + 'string_smth {id:"str", num:0}'.split('{')[-1]

我可以在您的文件中看到几个问题,但可能只是与您的示例相关的问题

我创建了一个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(路径到文件)
,以获取所需的文件。 如您所见,
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类不需要创建模式。

rdd = sc.textFile("path to the csv file")\
    .map(lambda line: line.split("\t", 1)[1].replace("id:", "\"id\":").replace("num:", "\"num\":"))
您可以使用
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 RDD转换为
dataframe

df = sqlContext.read.json(rdd)
应该给你什么

+----+---+
|id  |num|
+----+---+
|str |0  |
|str2|1  |
|str3|2  |
|str4|3  |
+----+---+

解决此问题的一种快速(但不干净的方法)是拆分“上的每一行”{'然后去掉第一部分。@ChukUltima,我会称之为狡猾的方式而不是肮脏的方式。请发布答案以帮助解决问题OP@ChukUltima顺便说一句,它们由一个制表符分隔。使用spark csv将其作为制表符分隔的文件读取,然后使用第二列上的
from_json
获得
结构(id,num)
@philantrovert找不到如何读取tsv的示例。你能发布一个吗?我需要PySpark中的这个。它是选项卡分隔的
字符串选项卡json\u dict
。我用
\t
更改了拆分。甚至更好;)@ivan\u bilan我忘记了
json。加载
函数。刚刚添加it@ivan_bilan你应该从SparkSessi获得sparkContext在…上object@ivan_bilan如果不是,则必须创建sparkContext对象,而不是sparkSession对象