在 pyspark 中处理大数字的数据类型

Posted

技术标签:

【中文标题】在 pyspark 中处理大数字的数据类型【英文标题】:datatype for handling big numbers in pyspark 【发布时间】:2016-04-01 06:37:14 【问题描述】:

我在 python 中使用 spark。上传 csv 文件后,我需要解析 csv 文件中包含 22 位数字长的列。为了解析该列,我使用了 LongType() 。我使用 map() 函数来定义列。 以下是我在 pyspark 中的命令。

>>> test=sc.textFile("test.csv")
>>> header=test.first()
>>> schemaString = header.replace('"','')
>>> testfields = [StructField(field_name, StringType(), True) for field_name in schemaString.split(',')]
>>> testfields[5].dataType = LongType()
>>> testschema = StructType(testfields)
>>> testHeader = test.filter(lambda l: "test_date" in l)
>>> testNoHeader = test.subtract(testHeader)
>>> test_temp = testNoHeader.map(lambda k: k.split(",")).map(lambda
p:(p[0],p[1],p[2],p[3],p[4],***float(p[5].strip('"'))***,p[6],p[7]))
>>> test_temp.top(2)

注意:我还在变量 test_temp 中尝试使用 'long' 和 'bigint' 代替 'float',但 spark 中的错误是 'keyword not成立' 以下是输出

[('2012-03-14', '7', '1698.00', 'XYZ02abc008793060653', 'II93', ***8.27370028700801e+21*** , 'W0W0000000000007', '879870080088815007'), ('2002-03-14', '1', '999.00', 'ABC02E000050086941', 'II93', 8.37670028702205e+21, 'A0B0080000012523', '870870080000012421')]

我的csv文件中的值如下: 8.27370028700801e+21 是 8273700287008010012345 8.37670028702205e+21 是 8376700287022050054321

当我用它创建一个数据框然后查询它时,

>>> test_df = sqlContext.createDataFrame(test_temp, testschema)
>>> test_df.registerTempTable("test")
>>> sqlContext.sql("SELECT test_column FROM test").show()

test_column 为所有记录提供值“null”。

那么,如何解决spark中解析大数字的问题,非常感谢您的帮助

【问题讨论】:

【参考方案1】:

嗯,类型很重要。由于您将数据转换为float,因此您不能在DataFrame 中使用LongType。它不只是因为 PySpark 在类型方面相对宽容。

另外,8273700287008010012345 太大,无法表示为 LongType,它只能表示 -9223372036854775808 和 9223372036854775807 之间的值。

如果要将数据转换为 DataFrame,则必须使用 DoubleType

from pyspark.sql.types import *

rdd = sc.parallelize([(8.27370028700801e+21, )])
schema = StructType([StructField("x", DoubleType(), False)])
rdd.toDF(schema).show()

## +-------------------+
## |                  x|
## +-------------------+
## |8.27370028700801E21|
## +-------------------+

通常最好直接使用DataFrames 处理此问题:

from pyspark.sql.functions import col

str_df = sc.parallelize([("8273700287008010012345", )]).toDF(["x"])
str_df.select(col("x").cast("double")).show()

## +-------------------+
## |                  x|
## +-------------------+
## |8.27370028700801E21|
## +-------------------+

如果您不想使用Double,您可以以指定的精度强制转换为Decimal

str_df.select(col("x").cast(DecimalType(38))).show(1, False)

## +----------------------+
## |x                     |
## +----------------------+
## |8273700287008010012345|
## +----------------------+

【讨论】:

以上是关于在 pyspark 中处理大数字的数据类型的主要内容,如果未能解决你的问题,请参考以下文章

在 pyspark 中转换或处理日期数据类型的最佳方法是啥

在 Pyspark/Hive 中处理不断变化的数据类型

在 pyspark 中操作 .txt 文件数据并更改数据类型

使用 PySpark 将字符串处理为 RDS 中的日期数据类型列

在pyspark中将字符串价格值转换为double类型

大数据搜索引擎 Elasticsearch 数字类型(numeric)数据的处理与搜索原理。