PyArrow Decimal128 精度管理:避免数据损失的舍入策略

PyArrow Decimal128 精度管理:避免数据损失的舍入策略

本文深入探讨了在pandas与pyarrow `decimal128`类型操作中遇到的精度管理挑战。当执行涉及`decimal128`类型的计算时,pyarrow会自动扩展精度,导致直接类型转换可能引发数据损失异常。文章详细解释了这一机制,并提供了一种通过在类型转换前进行显式舍入来有效解决数据损失问题的方法,确保金融计算结果的准确性和一致性。

引言:PyArrow decimal128 类型在金融计算中的应用

在处理金融数据时,浮点数(float)由于其固有的精度限制,常常导致计算结果不准确,尤其是在涉及货金额的乘法和除法运算中。为了解决这一问题,Python标准库提供了decimal.Decimal类型,而PyArrow则引入了decimal128数据类型,与Pandas的ArrowDtype结合使用,为大规模数据集的精确十进制运算提供了高效且可靠的解决方案。decimal128类型允许用户定义数据的总位数(precision)和小数点后的位数(scale),例如decimal128(12, 2)表示总共12位数字,其中2位在小数点之后。

理解精度扩展与数据损失问题

在使用PyArrow decimal128类型进行数值运算时,一个常见的挑战是PyArrow在内部处理精度的方式。当两个decimal128类型(或一个decimal128与一个decimal.Decimal)进行乘法等运算时,为了保留计算的中间结果,PyArrow会自动扩展结果的精度和刻度。

例如,一个decimal128(12, 2)类型的数据乘以decimal.Decimal(‘0.04’)(可以被视为具有隐式更高精度的十进制数),结果可能会自动提升为decimal128(15, 4)或其他更高的精度。这种行为旨在防止中间计算过程中的精度损失。

然而,当尝试将这种高精度结果直接强制转换回原始的低精度类型(例如,从decimal128(15, 4)转换回decimal128(12, 2))时,如果转换过程中存在小数位被截断的风险,PyArrow会抛出pyarrow.lib.ArrowInvalid: Rescaling Decimal128 value would cause data loss异常。这是因为PyArrow默认采用严格的类型转换策略,不会在没有明确指示的情况下进行舍入,以避免潜在的意外数据损失。用户明确的意图是舍入并截断,但PyArrow需要用户显式地表达这一意图。

此外,如果将decimal128类型与标准Python浮点数进行运算(例如df[‘Pay Rate’] * 0.04),结果可能会意外地转换为double[pyarrow]类型,这会丧失decimal128带来的精度优势。因此,在涉及decimal128的运算中,应尽量保持所有操作数的十进制类型一致性,例如使用decimal.Decimal而非float。

解决方案:显式舍入后再进行类型转换

解决ArrowInvalid: Rescaling Decimal128 value would cause data loss异常的关键在于,在执行类型转换(astype)之前,对数据进行显式的舍入操作。Pandas的Series对象提供了round()方法,可以指定需要保留的小数位数。通过先调用round()方法,我们明确告知系统按照预期的精度进行舍入,然后才能安全地将数据转换为目标decimal128类型。

示例代码

以下示例演示了如何通过显式舍入来管理decimal128的精度:

import pandas as pdimport pyarrow as pafrom decimal import Decimal# 1. 准备示例数据data = {    'col1': {0: Decimal('39.60'), 1: Decimal('39.60'), 2: Decimal('21.60'), 3: Decimal('7.20'), 4: Decimal('18.00'), 5: Decimal('18.00'), 6: Decimal('72.00'), 7: Decimal('30.60'), 8: Decimal('36.00'), 9: Decimal('41.40')},    'col2': {0: Decimal('0.98'), 1: Decimal('1.00'), 2: Decimal('0.97'), 3: Decimal('0.46'), 4: Decimal('0.52'), 5: Decimal('1.00'), 6: Decimal('1.00'), 7: Decimal('1.00'), 8: Decimal('1.00'), 9: Decimal('1.00')}}# 使用 PyArrow decimal128(12, 2) 类型创建 DataFramedf = pd.DataFrame(data, dtype=pd.ArrowDtype(pa.decimal128(12, 2)))print("原始 DataFrame 类型:")print(df.dtypes)print("n原始 DataFrame 数据:")print(df)# 2. 执行乘法运算,观察精度扩展# df['col1'] 是 decimal128(12, 2)# df['col2'] 也是 decimal128(12, 2)# 乘法结果的精度会自动扩展df['col3'] = df['col1'] * df['col2']print("n乘法运算后 col3 的类型:")print(df['col3'].dtype) # 结果可能是 decimal128(25, 4) 或类似更高的精度print("n乘法运算后 col3 的数据 (扩展精度):")print(df['col3'])# 3. 尝试直接进行类型转换(会导致数据损失异常)# try:#     df['col3_direct_cast'] = df['col3'].astype(pd.ArrowDtype(pa.decimal128(12, 2)))# except Exception as e:#     print(f"n直接类型转换失败,引发异常: {e}")# 4. 正确的解决方案:先舍入,再进行类型转换# 假设我们希望将结果保留两位小数df['col3_rounded_cast'] = df['col3'].round(2).astype(pd.ArrowDtype(pa.decimal128(12, 2)))print("n经过舍入并类型转换后 col3_rounded_cast 的类型:")print(df['col3_rounded_cast'].dtype) # 结果为 decimal128(12, 2)print("n经过舍入并类型转换后 col3_rounded_cast 的数据:")print(df['col3_rounded_cast'])# 验证一个具体的例子: 9.94 * 0.04 = 0.3976,期望舍入为 0.40# 如果 col1 或 col2 中有 9.94 和 0.04,我们可以观察# 假设我们手动创建一个例子test_df = pd.DataFrame({    'amount': [Decimal('9.94')],    'percentage': [Decimal('0.04')]}, dtype=pd.ArrowDtype(pa.decimal128(12, 2)))test_df['result'] = test_df['amount'] * test_df['percentage']print(f"n测试数据乘法结果类型: {test_df['result'].dtype}")print(f"测试数据乘法结果: {test_df['result'].iloc[0]}") # 预期 0.3976# 舍入并转换test_df['final_result'] = test_df['result'].round(2).astype(pd.ArrowDtype(pa.decimal128(12, 2)))print(f"测试数据舍入并转换后结果类型: {test_df['final_result'].dtype}")print(f"测试数据舍入并转换后结果: {test_df['final_result'].iloc[0]}") # 预期 0.40

在上述代码中,df[‘col3’].round(2)首先将col3中的所有值按照四舍五入规则保留两位小数。之后,astype(pd.ArrowDtype(pa.decimal128(12, 2)))操作就可以顺利进行,因为数据已经满足了目标类型的精度要求,不再存在需要截断的额外小数位。

注意事项与最佳实践

始终显式舍入: 在进行任何可能改变精度并需要强制转换回较低精度的操作时,务必在astype之前使用round()方法。这不仅避免了错误,也明确了业务逻辑中的舍入行为。选择合适的精度和刻度: 根据业务需求仔细选择decimal128(precision, scale)的参数。过高的精度可能导致不必要的存储和计算开销,而过低的精度则可能导致真正的业务数据损失。避免浮点数混合运算: 尽量避免将decimal128类型与Python内置的float类型混合运算,因为这可能导致结果类型退化为浮点数,从而丧失decimal128带来的精度优势。如果需要与常数运算,请使用decimal.Decimal对象(例如decimal.Decimal(‘0.04’))而不是0.04。理解舍入模式: Pandas的round()方法通常遵循“四舍五入到最近的偶数”(round half to even)的银行家舍入规则。在某些特定金融场景中,可能需要不同的舍入模式,此时需要额外实现或寻找支持特定舍入模式的库。中间计算的精度: 在一系列复杂的计算中,如果中间结果的精度要求高于最终结果,可以允许中间结果保持扩展的精度,只在最终需要存储或输出时进行舍入和类型转换。

总结

PyArrow decimal128类型为Pandas用户提供了强大的精确十进制计算能力,特别适用于金融应用。然而,其严格的类型系统在处理精度变化时需要用户额外关注。通过理解PyArrow自动扩展精度的机制,并采用“先显式舍入,后类型转换”的策略,可以有效避免ArrowInvalid: Rescaling Decimal128 value would cause data loss异常,确保计算结果的准确性和数据完整性。遵循这些最佳实践,将有助于构建更健壮、更可靠的数据处理流程。

以上就是PyArrow Decimal128 精度管理:避免数据损失的舍入策略的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1382807.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
如何在Python中动态创建全局变量
上一篇 2025年12月15日 00:33:36
Python高效生成与存储大规模内存访问轨迹的实践指南
下一篇 2025年12月15日 00:33:48

相关推荐

  • 怎么查看电脑配置信息?

    怎么查看电脑配置信息?怎么查看电脑配置信息?怎么查看电脑配置信息?怎么查看电脑配置信息?

    电脑的配置是评估一台电脑性能的重要指标,它直接影响到电脑的运行效率。电脑配置通常包括cpu、显卡、主板、内存、硬盘等多个方面。接下来,我将向大家介绍几种简单易懂的方式来查询电脑配置。 如何快速查看电脑配置呢?了解电脑配置对于选购或维护电脑的人来说至关重要,但很多人并不知道从哪里入手。实际上,查看电脑…

    2026年8月31日 用户投稿
    200
  • windows8怎么关闭搜索charm栏的bing网络搜索_windows8搜索Charm栏禁用Bing方法

    关闭Windows 8搜索Charm栏的Bing网络结果,需通过电脑设置禁用搜索建议、清除并禁用搜索历史记录,专业版用户还可通过组策略编辑器彻底禁用在线搜索功能。 如果您在使用Windows 8的搜索Charm栏时,发现其自动显示来自Bing的网络搜索结果,可能会影响本地搜索效率或隐私。以下是关闭该…

    2026年8月31日
    100
  • Win10安装后如何设置隐私_Win10隐私设置方法

    关闭活动历史记录、位置服务、传感器、广告ID及诊断数据,禁用Cortana数据收集,管理应用权限以保护隐私。 如果您在新安装的Windows 10系统后希望保护个人数据并防止不必要的信息收集,可以调整系统的隐私设置以限制应用和系统功能对敏感信息的访问。以下是具体的操作方法: 本文运行环境:Dell …

    2026年8月31日
    100
  • 共享打印机提示0X0000000d解决方法

    用户在使用win10系统时,遇到共享打印机显示错误代码0x0000000d的情况,这可能是首次遇到的问题。通常情况下,通过控制面板添加打印机可以解决问题。接下来,让我们一起了解win10共享打印机出现0x0000000d的解决办法。 win10共享打印机0X0000000d问题解决步骤: 1、点击开…

    2026年8月31日
    200
  • google浏览器怎么卸载干净_google浏览器彻底卸载方法

    通过系统设置卸载Chrome;2. 使用控制面板卸载并删除浏览数据;3. 手动删除AppData和ProgramData中的残留文件;4. 清理注册表中Google相关项;5. 删除Google更新任务并禁用更新服务,确保彻底移除。 如果您发现Google Chrome浏览器占用系统资源或与其他应用…

    2026年8月31日
    300
  • deepseek本地部署后怎么训练详细教程

    本文主要介绍在本地部署 DeepSee 模型并进行训练的详细教程。DeepSee 是一款用于理解和生成文本数据的先进自然语言处理模型。通过该教程,读者可以逐步了解如何设置 DeepSee 的本地环境,准备训练数据,配置模型参数,以及启动训练过程。通过遵循本教程,研究人员和机器学习从业人员可以充分利用…

    2026年8月31日
    200
  • Win10dns地址怎么设置?win10dns地址怎么设置的详细步骤

    Win10dns地址怎么设置?win10dns地址怎么设置的详细步骤Win10dns地址怎么设置?win10dns地址怎么设置的详细步骤Win10dns地址怎么设置?win10dns地址怎么设置的详细步骤Win10dns地址怎么设置?win10dns地址怎么设置的详细步骤

    安装windows 10系统之后,若想顺利上网,首先需要配置ip地址和dns服务器,这样可以确保网络连接既快速又稳定。以下为小编亲身测试过的具体操作步骤,大家可以跟着学习一下。 解决步骤: 在Windows 10系统的桌面,依次点击“开始 > Windows系统 > 控制面板”选项。 进…

    2026年8月31日 用户投稿
    100
  • win10系统如何使用cmd命令强制删除文件

    win10系统如何使用cmd命令强制删除文件win10系统如何使用cmd命令强制删除文件win10系统如何使用cmd命令强制删除文件win10系统如何使用cmd命令强制删除文件

    在使用windows 10的过程中,我们常常需要清理一些不再需要的文件以保持系统的整洁。然而,有时会遇到一些顽固的文件,这些文件用常规方法根本无法删除。这时,我们可以通过cmd命令行工具来实现强制删除操作。那么,如何在windows 10中利用cmd命令实现文件的强制删除呢?以下是具体的操作步骤: …

    2026年8月31日 用户投稿
    200
  • Linux规划、安装、远程管理

    在进行linux系统的硬盘规划时,必须根据服务项目来决定分区的大小和分配。 例如,如果系统是邮件主机,通常需要为/var分配几个GB的空间,以确保邮件存储空间充足。另一方面,如果是多用户多终端主机,/home分区通常需要更大的空间。这些规划都与预期的主机服务类型密切相关。 我的VMware中的Cen…

    2026年8月31日
    100
  • 千万不要装LTSC版Win10 LTSC版Win10优缺点分析

    windows 10 ltsc 是企业版的一种,称为 windows 10 企业版长期支持版,它不会强制性地进行更新。相信不少朋友已经有所耳闻,这款系统的优点不少,比如它没有任何预装的 uwp 应用,甚至连应用商店也没有。与普通版本每半年一次的大更新(如 1903 版、1909 版、2004 版)不…

    2026年8月31日
    400
  • 还在 SSH + Vim?VS Code 都支持远程开发了

    还在 SSH + Vim?VS Code 都支持远程开发了还在 SSH + Vim?VS Code 都支持远程开发了还在 SSH + Vim?VS Code 都支持远程开发了还在 SSH + Vim?VS Code 都支持远程开发了

    一.趋势 随着容器化和深度学习等技术在生产中的应用,越来越多的场景需要“远程”开发。例如: 服务器虚拟机容器等远程环境往往难以或无法在本地完全重建,比如: 特定配置:例如曾经遇到的 .Net Framework 4.0 + MSSQL 2000 ,以及安装了特定版本补丁的历史项目,几乎无法重现其环境…

    2026年8月31日 用户投稿
    200
  • 韩国大作《红色沙漠》预购开启:国区268元起!支持中文配音

    韩国大作《红色沙漠》预购开启:国区268元起!支持中文配音韩国大作《红色沙漠》预购开启:国区268元起!支持中文配音韩国大作《红色沙漠》预购开启:国区268元起!支持中文配音韩国大作《红色沙漠》预购开启:国区268元起!支持中文配音

    韩国游戏厂商Pearl Abyss备受期待的新作《红色沙漠》现已正式开启预购!游戏提供标准版与豪华版两种选择,Steam平台国区定价分别为268元和328元,PS5港服则为558港币与638港币。作品将于3月20日正式上线。 值得一提的是,Pearl Abyss通过其官方B站账号宣布,《红色沙漠》在…

    2026年8月31日 用户投稿
    200
  • Win7鼠标左右键互换怎么还原?

    Win7鼠标左右键互换怎么还原?Win7鼠标左右键互换怎么还原?Win7鼠标左右键互换怎么还原?Win7鼠标左右键互换怎么还原?

    有网友提问说,在win7系统下如何解决鼠标左右键互换的问题呢?所谓鼠标左右键互换,就是原本的左键变成了右键,而右键变成了左键,这种操作方式会让用户的使用变得非常不适应。那么,该如何恢复到原来的设置呢?接下来,就由小编为大家详细介绍具体的操作步骤。 具体操作步骤如下: 在win7系统中,设置鼠标的选项…

    2026年8月31日 用户投稿
    300
  • 抖音实名认证怎么可以认证两个号?有影响吗?

    想同时运营两个抖音账号,但担心实名认证只能绑定一个身份?其实,只要方法得当,完全可以在合规前提下实现双账号认证。本文将详细介绍如何用同一身份信息合理认证两个抖音号,并分析其中可能带来的影响与潜在风险。 一、抖音实名认证能否认证两个账号? 个人号+企业号组合:最推荐方案 你可以先用本人身份证认证一个个…

    2026年8月31日
    000
  • Win10 v2004如何移除Cortana开机启动项

    Win10 v2004如何移除Cortana开机启动项Win10 v2004如何移除Cortana开机启动项Win10 v2004如何移除Cortana开机启动项Win10 v2004如何移除Cortana开机启动项

    在本站之前发布的文章里,我们讲解了如何在Windows 10 May 2020(20H1/Version 2004)功能更新中卸载Cortana语音助手的小窍门。接下来,我们将介绍另一个方法,用于从开机启动项中移除Cortana。这个过程相当简便。 若想避免Cortana在开机时启动或在后台持续运行…

    2026年8月31日 用户投稿
    200
  • WPF 使用 Composition API 做高性能渲染

    在 wpf 中,许多开发者会遇到渲染性能的问题。尽管 wpf 的渲染性能比浏览器渲染要高出不少,但仍然无法满足游戏级别的渲染需求。wpf 使用的 directx 版本仅优化到 9 级别,与 directx 9 的性能相当。鉴于开发者的需求,微软推出了现代渲染方法——composition api,这…

    2026年8月31日
    200
  • win11电源计划选项不见了怎么恢复_win11电源计划选项丢失恢复教程

    首先通过注册表编辑器检查并修改NoClose键值为0,随后重启Windows资源管理器进程以刷新界面,接着使用管理员命令提示符执行powercfg -restoredefaultschemes恢复默认电源计划,最后运行sfc和DISM命令修复系统文件并安装最新更新,确保电源选项恢复正常。 如果您在W…

    2026年8月31日
    100
  • Windows 10 引入新功能:选择微软账户,抛弃本地账户

    Windows 10 引入新功能:选择微软账户,抛弃本地账户Windows 10 引入新功能:选择微软账户,抛弃本地账户Windows 10 引入新功能:选择微软账户,抛弃本地账户Windows 10 引入新功能:选择微软账户,抛弃本地账户

    N软网报道指出,在配置个人计算机时,如果选择本地账户,可能会发现Windows 10的一个新功能正频繁提示创建微软账户。自2024年5月14日起,这一功能将在Windows 10五月2024补丁周二更新中成为标准配置。 近年来,不借助微软账户操作Windows设备变得愈发复杂。近期的系统更新也推动了…

    2026年8月31日 用户投稿
    200
  • 微软承认 Win11 存在奇怪的打印机 Bug,但不影响使用

    近期,有用户反映,在运行 win10 和 win11 系统的非惠普设备上,microsoft store 会自动安装 hp smart 应用。对此,微软已经承认了这一情况,并且还证实了“打印机名称和图标可能发生变更”的问题。系统之家提示,这只是打印机名称有所改变,并不会影响打印机的实际使用。 根据微…

    2026年8月31日
    000
  • win10专业版打开第三方浏览器慢这样解决

    win10专业版启动第三方浏览器速度慢的问题困扰了不少从win7升级过来的用户。他们发现,尽管微软自家的edge浏览器浏览网页毫无问题,但第三方浏览器却经常出现加载缓慢甚至无法打开网页的情况。别担心,接下来就为大家介绍一种有效的解决办法。 解决win10专业版第三方浏览器启动慢的方法: 打开注册表编…

    2026年8月31日
    100

发表回复

登录后才能评论
关注微信