【问题标题】:Python modulo on np arrayPython对np数组取模
【发布时间】:2019-08-09 15:27:56
【问题描述】:

另一个问题Python modulo on floats 描述了为什么 Python 的模数在浮点数方面存在问题(我也知道计算机数字不是 essay 中所涵盖的数字,尤其是 3 的倍数)。但是,我在模数方面遇到了类似但不同的问题,并且接受的答案不起作用。

这是一个在 MacBook Pro 上使用 Python 3.7.1 可重现的示例:

import numpy as np
x = np.array([2.012, 2.012 *2, 2.012 *3, 2.012 *4, 2.012 *5, 2.012 *6])
x % 2.012
# array([0.0000000e+00, 0.0000000e+00, 2.0120000e+00, 0.0000000e+00,
#        4.4408921e-16, 2.0120000e+00])

如果我尝试接受的答案,我仍然会遇到同样的问题:

from decimal import Decimal
Decimal(3*2.012) % Decimal(2.012)
# Decimal('2.011999999999999566568931186')

我的具体问题:如何计算模数并为我的示例等系列取零?

根据反馈编辑:

作为一个具体的例子,如果我的数据看起来像这样(具体值将从实际数据中读取),我该如何做模运算符:

## X is read in from real data
x = np.array([2.012, 4.024, 6.036, 8.048, 1, 2, 3, 1.2, 1.3, 1.4, 1, 5, 6, 2.012, 2.012, 2.012])
[D(x) % D(frequency) for x in detections]
#[Decimal('0E-51'), Decimal('0E-51'), Decimal('2.011999999999999566568931186'), Decimal('0E-51'), Decimal('1.000000000000000000000000000'), Decimal('2.000000000000000000000000000'), Decimal('0.9879999999999999893418589636'), Decimal('1.199999999999999955591079015'), Decimal('1.300000000000000044408920985'), Decimal('1.399999999999999911182158030'), Decimal('1.000000000000000000000000000'), Decimal('0.9759999999999999786837179272'), Decimal('1.975999999999999978683717927'), Decimal('0E-51'), Decimal('0E-51'), Decimal('0E-51')]

【问题讨论】:

  • 初始值是作为浮点数提供还是作为实际数据中的文本提供?您需要从一开始就考虑将值转换为小数。
  • 它们将被 Pandas 或 numpy 读入。我还没有得到那部分代码。
  • 我认为它们中的任何一个都没有小数作为内置数据类型。在这种情况下,您可能需要考虑(1)使用整数表示,例如通过将值乘以 1000;或 (2) 保持浮点数表示并对模结果进行四舍五入。

标签: python numpy floating-point modulo


【解决方案1】:
In [6]: from decimal import Decimal as D
In [7]: D('3')*D('2.012') % D('2.012')
Out[7]: Decimal('0.000')

Python 在将参数传递给函数(或 Decimal 等可调用函数)之前评估参数。因此,如果要保留十进制值,则必须避免评估 float 3*2.012。因此,始终将小数的字符串表示形式传递给Decimal,而不是浮点数。


如果你有一个包含

的文本文件
2.012, 4.024, 6.036, 8.048, 1, 2, 3, 1.2, 1.3, 1.4, 1, 5, 6, 2.012, 2.012, 2.012

然后将值加载为字符串并将它们转换为Decimal,以避免将它们表示为浮点数。

import csv
from decimal import Decimal as D
freq = D('2.012')
with open('data', 'r') as f:
    reader = csv.reader(f)
    X = [D(item) for item in next(reader)]
    print([xi % freq for xi in X])

产量

[Decimal('0.000'), Decimal('0.000'), Decimal('0.000'), Decimal('0.000'), Decimal('1.000'), Decimal('2.000'), Decimal('0.988'), Decimal('1.200'), Decimal('1.300'), Decimal('1.400'), Decimal('1.000'), Decimal('0.976'), Decimal('1.976'), Decimal('0.000'), Decimal('0.000'), Decimal('0.000')]

由于 Decimals 不是 NumPy/Pandas 原生 dtype,因此将它们存储在 NumPy 数组或 Pandas 系列需要通用 object dtype。 NumPy/熊猫 不提供任何小数的矢量化操作,所以不会有 通过在此处使用 NumPy/Pandas 获得性能提升。

【讨论】:

  • 谢谢。您的回答有助于我更好地理解我的问题。我将根据您的回答编辑我的问题
猜你喜欢
  • 2011-11-04
  • 2019-10-11
  • 1970-01-01
  • 1970-01-01
  • 2018-08-28
  • 1970-01-01
  • 2022-06-11
  • 2023-02-10
  • 1970-01-01
相关资源
最近更新 更多