如何使用Pyspark将String类型列转换为Decimal类型列
解决方案
出现转换后全为null的核心原因有两个,对应解决方法如下:
- 原因1:设置的Decimal精度与数据不匹配
decimal(3,2)的定义是总位数共3位,小数点后占2位,意味着该类型最大只能存储9.99的数值,只要你的数据整数部分超过1位(比如10.25、123.4),就会溢出转换为null。
解决方法:
先确认你的数据范围,选择适配的精度参数,比如你的数据最高是999999.99,就用decimal(8,2)(总8位,小数点后2位),修改转换代码即可:
# 示例:使用适配大多数金额场景的decimal(10,2),可根据实际数据调整精度 df_line_items = df_line_items.withColumn("product_sold_price", df_line_items.product_sold_price.cast("decimal(10,2)"))
如果不确定数据范围,可以先执行以下代码查看字段最长长度,再确定精度:
from pyspark.sql.functions import length, max df_line_items.select(max(length("product_sold_price"))).show()
- 原因2:字符串列存在非法字符
如果你的原始字符串包含空格、货币符号($、¥等)、千位分隔符逗号,也会导致转换失败为null,需要先清洗字符再转换:
from pyspark.sql.functions import regexp_replace # 第一步:清洗掉所有非数字、非小数点的字符 df_line_items = df_line_items.withColumn("temp_clean_price", regexp_replace("product_sold_price", "[^0-9.]", "")) # 第二步:转换为对应精度的Decimal类型 df_line_items = df_line_items.withColumn("product_sold_price", df_line_items.temp_clean_price.cast("decimal(10,2)")) # 第三步:删除临时清洗列 df_line_items = df_line_items.drop("temp_clean_price")
如果调整后仍存在null值,可以执行以下代码定位转换失败的原始数据,针对性处理:
from pyspark.sql.functions import col df_line_items.filter(col("product_sold_price").isNull()).select("product_sold_price").show(20, truncate=False)
内容的提问来源于stack exchange,提问作者Timothy Clotworthy
相关产品推荐
相关产品推荐

