Pyspark Dataframe 创建 DecimalType 问题

Pyspark Dataframe Creation DecimalType issue

我正在尝试从 dict 列表和数据框的定义模式创建一个 pyspark 数据框。定义的架构中的一列是 DecimalType。创建数据框时出现错误;

TypeError: field b: DecimalType(38,18) can not accept object 0.1 in type <class 'float'>

test_data = [{"a": "1", "b": 0.1}, {"a": "2", "b": 0.2}]
schema = StructType(
    [
        StructField("a", StringType()),
        StructField("b", DecimalType(38, 18)),
    ]
)
# Create an dataframe
df = spark.createDataFrame(data = test_data,
                           schema = schema)

有人可以帮助解决这个问题。如何在列表中传递小数类型的数据?

改为FloatType

test_data = [{"a": "1", "b": 0.1}, {"a": "2", "b": 0.2}]
schema2 = StructType(
    [
        StructField("a", StringType()),
        StructField("b", FloatType()),
    ]
)

df = spark.createDataFrame(data=test_data,schema=schema2)
df.show()

+---+---+
|  a|  b|
+---+---+
|  1|0.1|
|  2|0.2|
+---+---+

如果您可能会损失一些准确性,那么您可以按照 建议将类型更改为 FloatType。
如果您需要更高的准确性,您也可以更改为 DoubleType。 FloatType 支持 4 个字节的信息,而 DoubleType 有 8 个字节(参见 here)。

如果您需要最高精度,您可以使用 Pythons Decimal 模块,默认情况下,点后有 28 位数字:

from pyspark.sql.types import *

from decimal import Decimal

test_data = [{"a": "1", "b": Decimal(0.1) }, {"a": "2", "b": Decimal(0.2) }]
schema = StructType(
    [
        StructField("a", StringType()),
        StructField("b", DecimalType(38, 18)),
    ]
)
# Create a dataframe
df = spark.createDataFrame(data = test_data,
                           schema = schema)

如果我们 运行 这个代码:

from pyspark.sql.types import *
from decimal import Decimal

test_data = [
  (1.9868968969869869045652421846, 1.9868968969869869045652421846, Decimal(1.9868968969869869045652421846)),
]

schema = StructType(
    [
        StructField("float_col", FloatType()),
        StructField("double_col", DoubleType()),
        StructField("decimal_col", DecimalType(38, 28)),
    ]
)
# Create an dataframe
df = spark.createDataFrame(data = test_data,
                           schema = schema)

我们会得到这样的区别: