Python Spark:解析具有相同模式的多个csv文件,这些文件具有任意恶意标题或不同编码
Spark 2.0.0+ 我使用内置的csv数据源直接将一些.csv文件(例如,Python Spark:解析具有相同模式的多个csv文件,这些文件具有任意恶意标题或不同编码,python,csv,apache-spark,pyspark,apache-spark-sql,Python,Csv,Apache Spark,Pyspark,Apache Spark Sql,Spark 2.0.0+ 我使用内置的csv数据源直接将一些.csv文件(例如,input\u file\u 01.csv,input\u file\u 02.csv等)解析为spark数据帧df: df = spark.read.csv('input_file_*.csv', header = True, inferSchema = False, # problematic col names trailing apostrophs sep
input\u file\u 01.csv
,input\u file\u 02.csv
等)解析为spark数据帧df
:
df = spark.read.csv('input_file_*.csv',
header = True,
inferSchema = False, # problematic col names trailing apostrophs
sep=';',
multiLine = False,
enforceSchema = True,
schema = jsonSchema,
mode='FAILFAST' # debug / DROPMALFORMED
)
它们都应该具有相同的模式(jsonSchema
)
问题:
Py4JJavaError: An error occurred while calling o9210.fromDF.:
org.apache.spark.sql.AnalysisException: cannot resolve '`F1`' given input columns: [F1, F2, F3];;
...
它们应该是相同的,但是某些具有恶意的头文件:
parsed_input_file_01.take(3)
>>>[u'"F1","F2","F3"',
u'"a","b","c"',
u'"d","e","f"']
回溯:
Py4JJavaError: An error occurred while calling o9210.fromDF.:
org.apache.spark.sql.AnalysisException: cannot resolve '`F1`' given input columns: [F1, F2, F3];;
...
问题:
Py4JJavaError: An error occurred while calling o9210.fromDF.:
org.apache.spark.sql.AnalysisException: cannot resolve '`F1`' given input columns: [F1, F2, F3];;
...
考虑到我不想删除整个文件的数据(例如通过.option('mode','dropmorformed')
,如果可能的话),我正在寻找一种通过(py)spark读取所有数据的高效方法
我的方法是单独解析所有文件的头,识别恶意文件,删除那些不需要的撇号或更改编码
Py4JJavaError: An error occurred while calling o9210.fromDF.:
org.apache.spark.sql.AnalysisException: cannot resolve '`F1`' given input columns: [F1, F2, F3];;
...
- 像
或quote
这样的常规选项无法解决标题随意更改的问题escaping
- 由于已知所需的架构(以及正确的(常规)列名和数据类型),因此不应推断该架构
- 所有csv文件都需要合并到一个数据帧中
dir_path = 'data'
data_rdd = sc.wholeTextFiles(dir_path)
data_flat_map = data_rdd.flatMap(lambda a: a[1].split()[1:])
d = data_flat_map.map(lambda a: a.split(","))
from pyspark.sql.types import *
schema = StructType([StructField("F1", StringType(), True),
StructField("F2", StringType(), True),
StructField("F3", StringType(), True)
])
df = spark.createDataFrame(d, schema)
让我知道这是否是你要找的
谢谢,
侯赛因·博拉(Hussain Bohra)引用不是问题。文件的不同之处在于在某些头文件中任意插入
”
(')。quote
或escaping
的常规选项无法解决此问题。此外,不应推断模式,因为我知道所需的模式(以及正确的(常规)列名)。此外,所有csv文件都需要合并到一个数据帧中。我明白了,对不起,我之前没有更好地看到问题陈述。看来你可能需要利用RDD。首先读取RDD中的数据,忽略第一行(标题)并从该行创建数据帧。我也会更新我的答案以反映同样的情况。谢谢你的输入。你的方法帮助我调试了这个问题。回溯是误导性的,因为似乎不是在模式或数据中,而是在错误消息本身中存在编码问题。实际的潜在缺陷似乎是列名的处理方式。模式实际上是由F.1
F.2
等定义的。这导致了问题。列名不应包含
。删除这些,在读取数据时不会导致问题。但该模式仍然无法正确识别。我将为spark发布关于列名中的点的错误报告。在读取时提供模式。阅读以下答案:提供了通用模式。但由于StructField
名称不匹配(由于不需要的'),某些文件无法正确读取。请参见文件17标题行的示例。