You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas处理缺失Decimal值序列化时返回null的实现方案问询

Serialize Pandas DataFrame with Decimal Type and Preserve Null Values in JSON

我完全懂你遇到的这个麻烦——把DataFrame列转成decimal.Decimal类型后,用to_json序列化直接炸出OverflowError,可你就想保留原有的null输出,还不能用float类型存储数据。

问题根源

原DataFrame里的None在float列中会被自动转为np.nan,当你直接用decimal.Decimal(x)处理这个np.nan时,会生成Decimal('NaN')。而Pandas默认的JSON序列化器在处理Decimal('NaN')时,会尝试把它转成浮点数的NaN,这就触发了OverflowError。另外,Pandas本身也没有内置对Decimal类型的序列化支持。

解决方案

要解决这个问题,我们需要分两步走:

  1. 先处理空值,避免生成Decimal('NaN');
  2. 自定义JSON序列化逻辑,让Decimal类型能被正确转换。

1. 正确转换Decimal类型并处理空值

修改apply的lambda函数,先判断输入是否为空(包括None和np.nan),为空就返回None,否则再转成Decimal:

df3 = df1.copy()
df3['A'] = df1['A'].apply(lambda x: decimal.Decimal(x) if pd.notna(x) else None)

2. 自定义JSON序列化函数

因为Pandas默认不支持Decimal的序列化,我们可以用Python标准库的json.dumps配合自定义编码器,把Decimal转成JSON支持的类型(如果要和原输出一致,转成float即可;如果需要精确表示,也可以转成字符串):

import json

def decimal_default(obj):
    if isinstance(obj, decimal.Decimal):
        return float(obj)  # 若需要精确字符串格式,替换为 str(obj)
    raise TypeError

然后用这个函数序列化DataFrame转成的字典列表:

json_result = json.dumps(df3.to_dict('records'), default=decimal_default)

完整代码示例

import pandas as pd
import numpy as np
import decimal
import json

data = [{'A': 0.1}, {'A': None}]
df1 = pd.DataFrame(data)
print("原df1序列化结果:")
print(df1.to_json(orient='records'))  # 输出:[{"A":0.1},{"A":null}]

# 转换为Decimal类型并处理空值
df3 = df1.copy()
df3['A'] = df1['A'].apply(lambda x: decimal.Decimal(x) if pd.notna(x) else None)

# 自定义序列化函数
def decimal_default(obj):
    if isinstance(obj, decimal.Decimal):
        return float(obj)  # 若需要精确字符串则改为 str(obj)
    raise TypeError

# 序列化df3
json_result = json.dumps(df3.to_dict('records'), default=decimal_default)
print("\ndf3序列化结果:")
print(json_result)  # 输出:[{"A": 0.1}, {"A": null}]

这样既保留了DataFrame中A列的Decimal类型,又能在JSON序列化时得到和原df1完全一致的输出。

内容的提问来源于stack exchange,提问作者Ashish Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:01:06