pyspark-java.lang.IllegalStateException:输入行没有架构所需的预期数量的值

时间:2018-09-09 18:21:05

标签: apache-spark pyspark-sql hortonworks-data-platform

我正在Horton沙箱上运行pyspark-sql代码

11/08/18 17:02:22信息spark.SparkContext:运行Spark版本1.6.3

# code 
from pyspark.sql import *
from pyspark.sql.types import *
rdd1 = sc.textFile ("/user/maria_dev/spark_data/products.csv")
rdd2 = rdd1.map( lambda x : x.split("," ) )
df1 = sqlContext.createDataFrame(rdd2, ["id","cat_id","name","desc","price", "url"])
df1.printSchema()

root
 |-- id: string (nullable = true)
 |-- cat_id: string (nullable = true)
 |-- name: string (nullable = true)
 |-- desc: string (nullable = true)
 |-- price: string (nullable = true)
 |-- url: string (nullable = true)

df1.show() 
+---+------+--------------------+----+------+--------------------+
| id|cat_id|                name|desc| price|                 url|
+---+------+--------------------+----+------+--------------------+
|  1|     2|Quest Q64 10 FT. ...|    | 59.98|http://images.acm...|
|  2|     2|Under Armour Men'...|    |129.99|http://images.acm...|
|  3|     2|Under Armour Men'...|    | 89.99|http://images.acm...|
|  4|     2|Under Armour Men'...|    | 89.99|http://images.acm...|
|  5|     2|Riddell Youth Rev...|    |199.99|http://images.acm...|

# When I try to get counts I get the following error.
df1.count()

**Caused by: java.lang.IllegalStateException: Input row doesn't have expected number of values required by the schema. 6 fields are required while 7 values are provided.**

# I get the same error for the following code as well
df1.registerTempTable("products_tab")
df_query = sqlContext.sql ("select id, name, desc from products_tab order by name, id ").show();

我看到desc列为空,不确定在创建数据框并对其使用任何方法时是否需要对空列进行不同的处理。

运行sql查询时发生相同的错误。看来sql错误是由于“ order by”子句引起的,如果我删除by by则查询成功运行。

如果需要更多信息,请告诉我,感谢您提供有关如何处理此错误的答案。

正如Chandan Ray所建议的,我试图查看名称字段是否包含任何逗号。 名称字段中没有逗号。

rdd1.count()
=> 1345
rdd2.count()
=> 1345
# clipping id and name column from rdd2
rdd_name = rdd2.map(lambda x: (x[0], x[2]) )
rdd_name.count()
=>1345
rdd_name_comma = rdd_name.filter (lambda x : True if x[1].find(",") != -1  else False )
rdd_name_comma.count()
==> 0

3 个答案:

答案 0 :(得分:0)

我想您的姓名字段中包含逗号,因此也将其拆分。所以它期望有7列

可能存在一些格式错误的行。

请尝试使用以下代码排除一个文件中的不良记录

val df = spark.read.format(“csv”).option("badRecordsPath", "/tmp/badRecordsPath").load(“csvpath”)

//它将读取csv并创建一个数据帧,如果有任何格式错误的记录,它将把它移到您提供的路径中。

//请阅读以下内容

https://docs.databricks.com/spark/latest/spark-sql/handling-bad-records.html

答案 1 :(得分:0)

我发现了问题-这是由于一个错误的记录所引起的,其中逗号被嵌入到字符串中。即使string被双引号括住,python也会将string分成2列。 我尝试使用databricks软件包

# from command prompt
pyspark --packages com.databricks:spark-csv_2.10:1.4.0

# on pyspark 
 schema1 = StructType ([ StructField("id",IntegerType(), True), \
         StructField("cat_id",IntegerType(), True), \
         StructField("name",StringType(), True),\
         StructField("desc",StringType(), True),\
         StructField("price",DecimalType(), True), \
         StructField("url",StringType(), True)
         ])

df1 = sqlContext.read.format('com.databricks.spark.csv').schema(schema1).load('/user/maria_dev/spark_data/products.csv')
        df1.show()
df1.show()
    +---+------+--------------------+----+-----+--------------------+
    | id|cat_id|                name|desc|price|                 url|
    +---+------+--------------------+----+-----+--------------------+
    |  1|     2|Quest Q64 10 FT. ...|    |   60|http://images.acm...|
    |  2|     2|Under Armour Men'...|    |  130|http://images.acm...|
    |  3|     2|Under Armour Men'...|    |   90|http://images.acm...|
    |  4|     2|Under Armour Men'...|    |   90|http://images.acm...|
    |  5|     2|Riddell Youth Rev...|    |  200|http://images.acm...|

df1.printSchema()
    root
     |-- id: integer (nullable = true)
     |-- cat_id: integer (nullable = true)
     |-- name: string (nullable = true)
     |-- desc: string (nullable = true)
     |-- price: decimal(10,0) (nullable = true)
     |-- url: string (nullable = true)

df1.count()
     1345

答案 2 :(得分:0)

这是我清理此类记录的方法,我们通常会遇到以下情况:

a。如果“,”是列上的最佳分隔符,则在创建文件时未发现数据异常。

这是我的解决方案:

解决方法a:在这种情况下,如果该记录是合格记录,我们希望将过程标识为数据清洗的一部分。其余记录如果路由到错误的文件/集合中,将有机会调和此类记录。

下面是我的数据集的结构(product_id,product_name,unit_price)

1,product-1,10
2,product-2,20
3,product,3,30

在上述情况下,应该将product,3读作product-3,这可能是注册产品时的错字。在这种情况下,下面的示例将起作用。

>>> tf=open("C:/users/ip2134/pyspark_practice/test_file.txt")
>>> trec=tf.read().splitlines()
>>> for rec in trec:
...   if rec.count(",") == 2:
...      trec_clean.append(rec)
...   else:
...      trec_bad.append(rec)
...
>>> trec_clean
['1,product-1,10', '2,product-2,20']
>>> trec_bad
['3,product,3,30']
>>> trec
['1,product-1,10', '2,product-2,20','3,product,3,30']

处理此问题的另一种方法是尝试查看skipinitialspace = True是否可以解析出列。

(参考号:Python parse CSV ignoring comma with double-quotes