每当我尝试在PySpark

时间:2018-12-31 20:05:15

标签: python apache-spark pyspark

已经有一段时间了,但是我又回来了。

问题: 当我尝试使用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,然后再次返回,当然,将其投射。可以肯定,这应该没那么难-那么我在哪里犯错了?

1 个答案:

答案 0 :(得分:1)

我认为逗号引起了麻烦。加载数据raw_df后,您可以将,替换为以下数量:

processed_df = raw_df.withColumn('Amount2', F.regex_replace('Total',',',''))