Python 使用spark读取数据时数据类型错误

Python 使用spark读取数据时数据类型错误,python,dataframe,apache-spark,pyspark,apache-spark-sql,Python,Dataframe,Apache Spark,Pyspark,Apache Spark Sql,如果我在使用pyspark读取文件时尝试指定模式,那么当模式不正确时,read方法不会失败。例如: schema = ''' { "fields": [ {"metadata":{},"name":"id0","nullable":true,"type":"integer"}, {"metadata":{},"name"

如果我在使用pyspark读取文件时尝试指定模式,那么当模式不正确时,read方法不会失败。例如:

schema = '''
{
"fields":
[
{"metadata":{},"name":"id0","nullable":true,"type":"integer"},
{"metadata":{},"name":"id1","nullable":true,"type":"integer"},
{"metadata":{},"name":"name","nullable":true,"type":"integer"},
{"metadata":{},"name":"timestamp","nullable":true,"type":"string"}
],"type":"struct"}
'''
schemaFromJson = StructType.fromJson(json.loads(schema))

df2 = spark.read.format("csv") \
      .option("header", True) \
      .schema(schemaFromJson) \
      .load(s3InputPath)
屈服

+----+----+----+---------+
| id0| id1|name|timestamp|
+----+----+----+---------+
|null|null|null|     null|
|null|null|null|     null|
|null|null|null|     null|
|null|null|null|     null|
+----+----+----+---------+
因为“name”字段是一个字符串,我告诉它读取为整数。 在这种情况下,有没有办法使read方法失败

数据样本:

id0,id1,name,timestamp
10,1,Name1,01/03/2021 13:00
10,2,Name2,01/03/2021 13:00
10,3,Name3,01/03/2021 13:00
10,4,Name4,01/03/2021 13:00

谢谢

您可以提供
mode=PERMISSIVE | FAILFAST | dropmorformed

场景1:将未处理的数据存储到另一列:

schema=''
{
“字段”:
[
{“metadata”:{},“name”:“id0”,“nullable”:true,“type”:“integer”},
{“metadata”:{},“name”:“id1”,“nullable”:true,“type”:“integer”},
{“metadata”:{},“name”:“name”,“nullable”:true,“type”:“integer”},
{“metadata”:{},“name”:“timestamp”,“nullable”:true,“type”:“string”},
{“metadata”:{},“name”:“{u corrupt\u record”,“nullable”:true,“type”:“string”}
],“类型”:“结构”}
'''
schemaFromJson=StructType.fromJson(json.loads(schema))
df2=spark.read.format(“csv”)\
.选项(“标题”,真)\
.选项(“columnNameOfCorruptRecord”,“\u corrupt\u record”)\
.schema(schemaFromJson)\
.load(s3InputPath,mode='PERMISSIVE')
df2.show()
场景2:引发异常

df2=spark.read.format(“csv”)\
.选项(“标题”,真)\
.schema(schemaFromJson)\
.load(s3InputPath,mode='FAILFAST')
场景3:仅处理有效数据

df2=spark.read.format(“csv”)\
.选项(“标题”,真)\
.schema(schemaFromJson)\
.load(s3InputPath,mode='DROPMALFORMED')
df2.show()

你能提供一个小数据样本吗?任何数据都可以。我在问题上加了一些。这太好了,非常感谢你的回答。我希望我能接受100次:)两个后续评论。由于spark的延迟加载特性(我相信),场景2中的错误只发生在show()命令上。你知道如何让它在网上发生吗?(除了可能在之后发布show()。第二个问题:在场景3中,有没有办法知道删除了多少行?再次感谢问题1:正如你所说,这是一个懒惰的负载。在引擎盖下,当spark开始读取您的文件时会引发异常,但这只会在操作调用(显示、计数、收集、写入等)后触发。问题2:更简单的方法是使用
mode=PERMISSIVE
并应用
.where
条件来过滤所有记录不为空的行。据我所知,
DROPMALFORMED
选项没有存储任何关于删除多少记录的元数据
Output:
+---+---+--------+----------------+--------------------+
|id0|id1|    name|       timestamp|     _corrupt_record|
+---+---+--------+----------------+--------------------+
| 10|  1|    null|01/03/2021 13:00|10,1,Name1,01/03/...|
| 10|  2|    null|01/03/2021 13:00|10,2,Name2,01/03/...|
| 10|  3|    null|01/03/2021 13:00|10,3,Name3,01/03/...|
| 10|  4|    null|01/03/2021 13:00|10,4,Name4,01/03/...|
| 10|  5|40028922|01/03/2021 13:00|                null|
+---+---+--------+----------------+--------------------+
Output:
[...]
Caused by: org.apache.spark.sql.catalyst.util.BadRecordException: java.lang.NumberFormatException: For input string: "Name1"
[...]
Output:
+---+---+--------+----------------+
|id0|id1|    name|       timestamp|
+---+---+--------+----------------+
| 10|  5|40028922|01/03/2021 13:00|
+---+---+--------+----------------+