已经有一段时间了,但是我又回来了。
问题:
当我尝试使用PySpark将StringType类型的任何列转换为DecimalType(和FloatType)时,返回的是空值。像F.substring
这样的方法仍然可以在列上使用,因此即使我已尽一切努力将其指向正确的方向,也显然仍将其视为字符串。
复制: 范例csv:
Currency,Total
USD,"3,472.43"
示例.py文件:
from pyspark.sql import DataFrame, SparkSession, types, functions as F
from pyspark.sql.types import StructField, StringType, DoubleType, TimestampType
def transform():
spark = SparkSession.builder.appName(
"Example for StackOverflow").enableHiveSupport().getOrCreate()
raw_df = spark.read.csv('ex.csv', header=True)
processed_df = \
raw_df.withColumn('Amount2', F.col('Total').cast(types.DecimalType()))
processed_df.show()
processed_df = \
raw_df.withColumn('Amount3', F.substring(F.col('Total'), 0, 4))
processed_df.show()
processed_df = \
raw_df.withColumn('Amount2', F.col('Total').cast(types.DecimalType()))
processed_df.show()
transform()
运行时,给出以下输出:
+--------+--------+-------+
|Currency| Total|Amount2|
+--------+--------+-------+
| USD|3,472.43| null|
+--------+--------+-------+
+--------+--------+-------+
|Currency| Total|Amount3|
+--------+--------+-------+
| USD|3,472.43| 3,47|
+--------+--------+-------+
+--------+--------+-------+
|Currency| Total|Amount2|
+--------+--------+-------+
| USD|3,472.43| null|
+--------+--------+-------+
不是很了解这里的电线在哪里交叉。
尝试的解决方案:
我已经尝试了几乎所有可以想到的方法-使用StructType
(将一切为null),使用各种类型(DecimalType,FloatType等),将inferSchema从true更改为false,然后再次返回,当然,将其投射。可以肯定,这应该没那么难-那么我在哪里犯错了?
答案 0 :(得分:1)
我认为逗号引起了麻烦。加载数据raw_df
后,您可以将,
替换为以下数量:
processed_df = raw_df.withColumn('Amount2', F.regex_replace('Total',',',''))