我有大量的小镶木地板。其中 80% 的
year
列编码为 int,但 20% 为 'Int64'
我通过指定架构来读取它们,其中我将年份列指定为 IntegerType。
df = Spark.read.schema(myschema).parquet('gs://path/myfiles/')
但是当我尝试写 df 时:
df.write.parquet('gs://myresults/')
我收到错误:
Parquet column cannot be converted in file <parquet path> Column: [year], Expected: int, Found: INT64
我尝试过显式转换:
df = df.select(col('year').cast(IntegerType))
df.write.parquet('gs://myresults/')
我仍然收到此错误。 如何避免这种铸造错误?
在下面查找快速示例数据,以测试和观察将
cast(IntegerType)
应用于 LongType
数据类型列时的精度损失(例如,在下面的示例中,3000000000000000001 在转换后为 413007873)。
一种方法是:
year
列数据类型定义为 LongType
。year
大于最大IntegerType
允许的行(例如2147483647),并且也许将它们保存到错误表中以供事后分析。cast(IntegerType)
功能并写入数据。--- 代码 ---
from pyspark.sql.types import StructType, StructField, StringType, IntegerType, LongType
from pyspark.sql.functions import col
data = [("A","B",300000000000000001), ("C","D",4001), ("E","F",4002)]
schema = StructType([StructField("firstname",StringType(),True), StructField("lastname",StringType(),True), StructField("salary", LongType(), True)])
df = spark.createDataFrame(data=data, schema=schema)
df = df.withColumn("salary",df.salary.cast(IntegerType()))
df.printSchema()
df.show()
--- 输出---
root
|-- firstname: string (nullable = true)
|-- lastname: string (nullable = true)
|-- salary: integer (nullable = true)
+---------+--------+---------+
|firstname|lastname| salary|
+---------+--------+---------+
| A| B|413007873|
| C| D| 4001|
| E| F| 4002|
+---------+--------+---------+