Python 在将JSON文件读入PySpark数据帧之前过滤JSON文件中的垃圾
我有以下文件,它应该是一个JSON文件,但它在实际JSON内容之前有一个字符串(它们由一个选项卡分隔!): 执行以下操作将为所有列返回null: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
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对象