Pyspark 读取文件并将其附加到spark数据帧中

Pyspark 读取文件并将其附加到spark数据帧中,pyspark,Pyspark,我已经创建了一个空数据框,并开始通过读取每个文件来添加它。但其中一个文件的列数比前一个文件的列数多。如何为所有其他文件仅选择第一个文件中的列 from pyspark.sql import SparkSession from pyspark.sql import SQLContext from pyspark.sql.types import StructType import os, glob spark = SparkSession.builder.\ co

我已经创建了一个空数据框,并开始通过读取每个文件来添加它。但其中一个文件的列数比前一个文件的列数多。如何为所有其他文件仅选择第一个文件中的列

from pyspark.sql import SparkSession

from pyspark.sql import SQLContext

from pyspark.sql.types import StructType
import os, glob
spark = SparkSession.builder.\           
    config("spark.jars.packages","saurfang:spark-sas7bdat:2.0.0-s_2.11")\            
    .enableHiveSupport().getOrCreate()
fpath=''
schema = StructType([])
sc = spark.sparkContext
df_spark=spark.createDataFrame(sc.emptyRDD(), schema)
files=glob.glob(fpath +'*.sas7bdat')
for i,f in enumerate(files):
    if i == 0:
       df=spark.read.format('com.github.saurfang.sas.spark').load(f)   
       df_spark= df
    else:
         df=spark.read.format('com.github.saurfang.sas.spark').load(f) 
         df_spark=df_spark.union(df)

您可以从第一个文件的架构中获取字段名,然后使用字段名数组从所有其他文件中选择列

fields = df.schema.fieldNames
可以使用字段数组从所有其他数据集中选择列。下面是这方面的scala代码

df=spark.read.format('com.github.saurfang.sas.spark').load(f).select(fields(0),fields.drop(1):_*)

您可以在创建数据帧时提供自己的模式。 例如,我有两个文件
emp1.csv&emp2.csv
具有不同的模式

id,empname,empsalary
1,Vikrant,55550

id,empname,empsalary,age,country
2,Raghav,10000,32,India

schema = StructType([
            StructField("id", IntegerType(), True),
            StructField("name", StringType(), True),
            StructField("salary", IntegerType(), True)])

file_path="file:///home/vikct001/user/vikrant/inputfiles/testfiles/emp*.csv"
df=spark.read.format("com.databricks.spark.csv").option("header", "true").schema(schema).load(file_path)
指定模式不仅可以解决数据类型和格式问题,而且对于提高性能也是必要的

如果需要删除格式错误的记录,还可以使用其他选项,但这也会删除具有空值或不符合提供的模式的记录。 它可能会跳过那些同时具有多个分隔符和垃圾字符或空文件的记录

.option("mode", "DROPMALFORMED")
FAILFAST模式在发现格式错误的记录时将引发异常

.option("mode", "FAILFAST")
在构建数据帧时,还可以使用映射函数选择所选元素并排除其他元素

df=spark.read.format('com.databricks.spark.csv').option("header", "true").load(file_path).rdd.map(lambda x :(x[0],x[1],x[2])).toDF(["id","name","salary"])

在这两种情况下,您都需要将标题设置为“true”,否则它将包括您的csv标题作为数据帧的第一条记录。

df=spark.read.format(“com.databricks.spark.csv”).option(“header”、“true”).schema(schema).load(file_path)对我有效,而不是数据类型不匹配。找不到导致问题的确切行的详细信息。谢谢你,维克兰特·拉娜。那就行了。当您必须删除不按特定顺序排列的列或必须删除中间的列时,rdd方法将非常有用。在这种情况下,您可能还需要修改map函数。我的意思是这取决于你的要求。
df=spark.read.format('com.databricks.spark.csv').option("header", "true").load(file_path).rdd.map(lambda x :(x[0],x[1],x[2])).toDF(["id","name","salary"])