【问题标题】:Python as_dict() converting decimal values 0.0 as decimal(0)Python as_dict() 将十进制值 0.0 转换为 decimal(0)
【发布时间】:2020-11-23 12:57:10
【问题描述】:

我有一个 spark 数据框,我正在尝试将其转换为字典列表。我正在这样做,

list(map(lambda row: row.asDict(), df.collect()))

但这会将数据框中的一些十进制值从0.0 转换为decimal(0)

预期:

[{'Name': 'John','Weight': 0.0, '_id': '0010z00001aZa0RAAS'}]

实际:

[{'Name': 'John','Weight': Decimal('0'), '_id': '0010z00001aZa0RAAS'}]

编辑

我需要这个,因为我必须将这个确切的列表传递给 MongoDB 进行存储,而 PyMongo 不支持 Decimal('0') 并抛出如下错误:

MongoDB ERROR: data not inserted: cannot encode object: Decimal('0'), of type: <class 'decimal.Decimal'>

我也尝试将 spark df 转换为 pandas df json.loads(df.toPandas().T.to_json())).values() 获取字典。但是这种方法似乎很慢。

我错过了什么?我是新来的。感谢您的帮助

【问题讨论】:

  • 为什么会有问题?鉴于鸭子类型的概念,小数点零是否有过不按你想要的方式嘎嘎叫的时候?
  • 因为我必须将这个确切的列表传递给 MongoDB 进行存储。 PyMongo 不支持这个。
  • 您可能应该在问题中提及这一点,可能是帮助您发现这一点的例外。
  • @MadPhysicist:十进制对象在正常使用中不会像浮点数那样嘎嘎作响。 decimal.Decimal('0')+1.0 引发 TypeError。
  • @Ahalya。您是否接受修复输出或使数据库输入工作的解决方案?还是你更喜欢前者?

标签: python dataframe dictionary pyspark


【解决方案1】:

阿哈利亚, 我认为您可以通过将权重从小数转换为浮点数来实现这一点

[{'Name': 'John','Weight': 0.0, '_id': '0010z00001aZa0RAAS'}] 这是示例代码:

from pyspark.sql.functions import col

df = ...
df = df.withColumn("weight", col("weight").cast("float"))
df_dict = list(map(lambda row: row.asDict(), df.collect()))

你会得到 0.0 而不是 Decimal(0,0)

编辑 1: 如果您必须检查十进制列并动态转换它们:

column_schema = df.dtypes
for cols in column_schema:
    if 'decimal' in cols[1]:
        df = df.withColumn(cols[0], col(cols[0]).cast("float")) 

说明: 在 columns_schema 中,您从数据框中收集 column_name、数据类型为 list(tuple(column,datatype))。 稍后您使用 column_schema 循环数据帧并将数据类型为 decimal(0,0) 的列转换为浮点数。

我同意这是一种粗略的做法,但我只是为您提供一种方法,您可以以更好的方式对其进行改进。 希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 2018-09-22
    • 1970-01-01
    • 2010-12-15
    • 2011-08-13
    • 1970-01-01
    • 2015-08-25
    • 2020-06-20
    • 2017-04-11
    • 2014-02-05
    相关资源
    最近更新 更多