在PySpark中读取csv文件

时间:2019-12-16 15:47:06

标签: apache-spark pyspark databricks

我正在尝试读取csv文件并将其转换为dataframe。 input.txt

 4324,'Andy',43.5,20.3,53.21 

 2342,'Sam',22.1 

 3248,'Jane',11.05,12.87

 6457,'Bob',32.1,75.23,71.6

模式:ID,名称,一月,二月,三月

如您所见,如果没有尾随费用,csv文件中没有“”。

代码:

from pyspark.sql.types import *
input1= sc.textFile('/FileStore/tables/input.txt').map(lambda x: x.split(","))

schema = StructType([StructField('Id',StringType(),True), StructField('Name',StringType(),True), StructField('Jan',StringType(),True), StructField('Feb',StringType(),True), StructField('Mar',StringType(),True)])

df3 = sqlContext.createDataFrame(input1, schema)

我得到ValueError:对象(4)的长度与字段(5)的长度不匹配。我该如何解决?

3 个答案:

答案 0 :(得分:2)

from pyspark.sql.types import *

from pyspark.sql import SparkSession

spark = SparkSession.builder.appName("Test").getOrCreate()

fields = [StructField('Id', StringType(), True), StructField('Name', StringType(), True),
          StructField('Jan', StringType(), True), StructField('Feb', StringType(), True),
          StructField('Mar', StringType(), True)]

schema = StructType(fields)

data = spark.read.format("csv").load("test2.txt")

df3 = spark.createDataFrame(data.rdd, schema)
df3.show()

Output:

+----+------+-----+-----+-----+
|  Id|  Name|  Jan|  Feb|  Mar|
+----+------+-----+-----+-----+
|4324|'Andy'| 43.5| 20.3|53.21|
|2342| 'Sam'| 22.1| null| null|
|3248|'Jane'|11.05|12.87| null|
|6457| 'Bob'| 32.1|75.23| 71.6|
+----+------+-----+-----+-----+

答案 1 :(得分:1)

我将首先使用pandas导入文件,它应该为您处理所有事情。然后,您可以从那里将pandas DataFrame转换为spark并执行所有常规操作。我复制了您的示例txt文件,并迅速编写了一些代码来确认它可以正常工作:

import pandas as pd

# Reading in txt file as csv
df_pandas = pd.read_csv('<your location>/test.txt', 
                        sep=",")

# Converting to spark dataframe and displaying
df_spark = spark.createDataFrame(df_pandas)
display(df_pandas)

产生了以下输出:

enter image description here

更快的方法是通过spark导入:

# Importing csv file using pyspark
csv_import = sqlContext.read\
                       .format('csv')\
                       .options(sep = ',', header='true', inferSchema='true')\
                       .load('<your location>/test.txt')


display(csv_import)

给出相同的输出。

答案 2 :(得分:0)

这里有几个选项供您考虑。这些使用通配符,因此您可以循环浏览所有文件夹和子文件夹,查找名称与特定模式匹配的文件,并将所有内容合并为单个数据框。

val myDFCsv = spark.read.format("csv")
   .option("sep",",")
   .option("inferSchema","true")
   .option("header","true")
   .load("mnt/rawdata/2019/01/01/client/ABC*.gz")

myDFCsv.show()
myDFCsv.head()
myDFCsv.count()


//////////////////////////////////////////
// If you also need to load the filename
import org.apache.spark.sql.functions.input_file_name
val myDFCsv = spark.read.format("csv")
   .option("sep",",")
   .option("inferSchema","true")
   .option("header","true")
   .load("mnt/rawdata/2019/01/01/client/ABC*.gz")
   .withColumn("file_name",input_file_name())


myDFCsv.show(false)
myDFCsv.head()
myDFCsv.count()