Python Spark:解析具有相同模式的多个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

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=';',
         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读取所有数据的高效方法

我的方法是单独解析所有文件的头,识别恶意文件,删除那些不需要的撇号或更改编码

  • 如何识别spark中的错误文件或不同编码
  • 是否有一种高效的方法可以首先解析头文件,并通过在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文件都需要合并到一个数据帧中

    您可能需要在此处使用RDD:

    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标题行的示例。