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

Apache spark pyspark-java.lang.IllegalStateException:输入行没有架构所需的预期值数,apache-spark,pyspark-sql,hortonworks-data-platform,Apache Spark,Pyspark Sql,Hortonworks Data Platform,我正在霍顿沙盒上运行pysparksql代码 18/08/11 17:02:22信息spark.SparkContext:运行spark版本1.6.3 我看到column desc为null,不确定在创建数据帧和对其使用任何方法时是否需要对null列进行不同的处理 运行sql查询时也会发生相同的错误。sql错误似乎是由于ORDERBY子句造成的,若我删除ORDERBY,那个么查询将成功运行 请让我知道,如果你需要更多的信息,并感谢回答如何处理这个错误 我试着看看name字段是否包含任何逗号,正如

我正在霍顿沙盒上运行pysparksql代码

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

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

运行sql查询时也会发生相同的错误。sql错误似乎是由于ORDERBY子句造成的,若我删除ORDERBY,那个么查询将成功运行

请让我知道,如果你需要更多的信息,并感谢回答如何处理这个错误

我试着看看name字段是否包含任何逗号,正如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

我想您的名称字段中有逗号,所以它也会将其拆分。所以它需要7列

可能有一些格式不正确的行

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

val df = spark.read.format(“csv”).option("badRecordsPath", "/tmp/badRecordsPath").load(“csvpath”)
//它将读取csv并创建一个数据帧,如果有任何格式不正确的记录,它会将其移动到您提供的路径中

//请阅读下面的内容


我发现了这个问题——这是由于一个坏记录造成的,字符串中嵌入了逗号。即使字符串是双引号的,python也会将字符串拆分为两列。 我试着使用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

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

a。如果文件创建时是列上的最佳分隔符,则未查看数据上的异常

以下是我对该案例的解决方案:

解决方案a:在这种情况下,如果该记录是合格记录,我们希望将该过程标识为数据清理的一部分。如果将其余记录发送到错误的文件/集合,则有机会核对这些记录

下面是我的数据集产品id、产品名称、单价的结构

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是否能够解析出列


Ref:

谢谢Chandan调查我的问题。我在名称字段中没有看到任何逗号。请看我的原始帖子,我已经添加了代码来检查名称字段中的逗号。请提供一些数据的示例行谢谢Chandan,这是数据问题。我觉得很难但是您可以使用上面的答案来过滤出格式错误的数据。请使用它并检查Chandan,我正在使用spark 1.6.3,我尝试使用与您提供的代码类似的代码。它导致错误::java.lang.ClassNotFoundException:未能找到数据源:csv。请在找到包裹。我猜csv格式在1.6.3中不可用。我使用了csv解决方案,使用了我在文章中提到的databricks包。谢谢你的帮助,谢谢希曼苏。您提供的解决方案干净且易于遵循。这里我看到的唯一问题是,很少有在双引号中嵌入逗号的记录会从处理中删除。当我使用databricks软件包时,它可以像预期的那样工作,即使用不带引号的逗号作为分隔符。
>>> 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']