1

我有一个随着循环的每次迭代而增长的数组:

for i in range(100):
    frac[i] = some fraction between 0 and 1 with many decimal places

这一切都很好。当我检查type(frac[i])时,我被告知它是'numpy.float64'

为了使我的代码尽可能精确,我需要使用十进制模块并将每个frac[i]更改为十进制类型。

我更新了我的代码:

for i in range(100):
    frac[i] = some fraction between 0 and 1 with many decimal places

    frac[i] = decimal.Decimal(frac[i])

但是当我检查类型时,我仍然被告知frac[i]'numpy.float64'

我之前已经设法以这种方式将其他变量更改为十进制,所以我想知道您是否可以告诉我为什么这似乎不起作用。

谢谢你。

4

4 回答 4

1

注意:我根本没有使用numpy过,所以接下来的内容主要只是一个有根据的猜测。

听起来您正在使用 type 的类型化数组float64。类型化数组是一个特殊的特性numpy——Python 本身中的数组元素(实际上是列表)可以在类型之间动态变化,并且 Python 列表中的所有元素不需要具有相同的类型。

使用float64-type 数组,您的值将被转换为浮点数,因为它们被分配给数组元素,从而撤消您在此之前对它们所做的任何类型转换。

numpy 数组创建的文档提到默认数组类型是float64. 您可能需要将其更改为Decimal.

将关键字参数添加dtype=Decimal到调用np.arange应该这样做。然后,您应该有一个 type 数组Decimal,并且您分配给它的任何一个float或多个float64值都应该转换为 Decimal。我对你在做什么,或者对 numpy 的了解不够,不知道用 numpy 数组做这件事是否明智。

于 2013-08-31T22:46:15.990 回答
1

我只是在用 Numpy 玩小数。

我发现 Numpy 提供了一个名为 np.vectorize 的函数,它允许您获取一个函数并将其应用于一个 numpy 数组。在[23]中:

import numpy as np

import decimal

D = decimal.Decimal

​</p>

我们将创建一个常规的 np 浮点数组

在[24]中:

f10 = np.random.ranf(10)

f10

出[24]:

array([ 0.45410583,  0.35353919,  0.5976785 ,  0.12030978,  0.00976334,
        0.47035594,  0.76010096,  0.09229687,  0.24842551,  0.30564141])

尝试使用 np.asarray 将数组转换为 Decimal 类型不起作用。似乎尝试使用 np.asarray 并指定 decimal.Decimal 类型将数组设置为预期的对象,但如果您实际访问数组的单个元素,它仍然具有浮点数据类型。在[25]中:

f10todec = np.asarray(f10, dtype = decimal.Decimal)

print f10todec.dtype, f10todec

print type(f10todec[0])

object [0.454105831376884 0.3535391906233327 0.5976785016396975 0.1203097778312584
 0.009763339031407026 0.47035593879363524 0.7601009625324361
 0.09229687387940333 0.24842550566826282 0.30564141425653435]
<type 'float'>

如果你给 np.array 一个同质的十进制类型 python 列表,那么它似乎保留了类型,因此下面的列表理解将第一个数组中的值列表作为十进制数据类型。所以我不得不以这种方式制作十进制数组。

在[26]中:

D10 = np.array([D(d) for d in f10])

D10

出[26]:

array([Decimal('0.4541058313768839838076019077561795711517333984375'),
       Decimal('0.35353919062333272194109667907468974590301513671875'),
       Decimal('0.597678501639697490332991947070695459842681884765625'),
       Decimal('0.12030977783125840208100498784915544092655181884765625'),
       Decimal('0.00976333903140702563661079693702049553394317626953125'),
       Decimal('0.47035593879363524205672320022131316363811492919921875'),
       Decimal('0.76010096253243608632743644193396903574466705322265625'),
       Decimal('0.09229687387940332943259136300184763967990875244140625'),
       Decimal('0.24842550566826282487653543284977786242961883544921875'),
       Decimal('0.30564141425653434946951847450691275298595428466796875')], dtype=object)

基本的数学运算似乎工作正常

在[27]中:

D10/2

出[27]:

array([Decimal('0.2270529156884419919038009539'),
       Decimal('0.1767695953116663609705483395'),
       Decimal('0.2988392508198487451664959735'),
       Decimal('0.06015488891562920104050249392'),
       Decimal('0.004881669515703512818305398469'),
       Decimal('0.2351779693968176210283616001'),
       Decimal('0.3800504812662180431637182210'),
       Decimal('0.04614843693970166471629568150'),
       Decimal('0.1242127528341314124382677164'),
       Decimal('0.1528207071282671747347592373')], dtype=object)

在[28]中:

np.sqrt(D10)

出[28]:

array([Decimal('0.6738737503248542354573624759'),
       Decimal('0.5945916166776426405934196108'),
       Decimal('0.7730966961769384578392278689'),
       Decimal('0.3468569991095154505863255680'),
       Decimal('0.09880961001545864636229121433'),
       Decimal('0.6858250059553349663476168402'),
       Decimal('0.8718376927688066448819998853'),
       Decimal('0.3038040057000620415496242404'),
       Decimal('0.4984230187985531079935481296'),
       Decimal('0.5528484550548498633920483390')], dtype=object)

直到您尝试在 [29] 中的十进制模块中没有相应函数的三角函数:

np.sin(D10)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)

<ipython-input-29-31ba62da35b8> in <module>()
----> 1 np.sin(D10)

AttributeError: 'Decimal' object has no attribute 'sin'

所以让我们使用 np.vectorize 以便我们可以使用小数的量化函数进行舍入。

In [30]:

    npquantize = np.vectorize(decimal.Decimal.quantize)

    qnt_D10 = npquantize(D10, D('.000001'))

    qnt_D10

Out[30]:

    array([Decimal('0.454106'), Decimal('0.353539'), Decimal('0.597679'),
           Decimal('0.120310'), Decimal('0.009763'), Decimal('0.470356'),
           Decimal('0.760101'), Decimal('0.092297'), Decimal('0.248426'),
           Decimal('0.305641')], dtype=object)

您还需要小心一些常规的 Python 数学函数,因为它们会自动将返回类型更改为浮点数。我认为这是因为无法根据 SIN 或 COS 等函数准确计算数字。

所以我想简短的答案是使用列表推导来获取numpy数组中的项目并将其转换为python列表,然后从小数列表中创建该数组。

要返回类型完整的 numpy 数组,我想您可以使用 vectorize 函数来包装任何适用于 Decimal 类型的函数以应用于 np 数组。

附带说明一下,pip 中有一个模块,它提供带有 IEEE 小数的 numpy 样式数组https://pypi.python.org/pypi/decimalpy/0.1

于 2015-04-10T05:22:29.613 回答
1

根据分数的来源,您可能会发现使用分数模块是理想的。文档中的一些示例:

>>> from fractions import Fraction
>>> Fraction(16, -10)
Fraction(-8, 5)
>>> Fraction(123)
Fraction(123, 1)
>>> Fraction()
Fraction(0, 1)
>>> Fraction('3/7')
Fraction(3, 7)
>>> Fraction(' -3/7 ')
Fraction(-3, 7)
>>> Fraction('1.414213 \t\n')
Fraction(1414213, 1000000)
>>> Fraction('-.125')
Fraction(-1, 8)
>>> Fraction('7e-6')
Fraction(7, 1000000)
>>> Fraction(2.25)
Fraction(9, 4)
>>> Fraction(1.1)
Fraction(2476979795053773, 2251799813685248)
>>> from decimal import Decimal
>>> Fraction(Decimal('1.1'))
Fraction(11, 10)

您还可以执行所有常规算术运算;如果结果不能表示为分数,则将其转换为浮点数:

>>> Fraction(3, 4) + Fraction(1, 16)
Fraction(13, 16)
>>> Fraction(3, 4) * Fraction(1, 16)
Fraction(3, 64)
>>> Fraction(3, 4) ** Fraction(1, 16)
0.982180548555
于 2013-08-31T17:42:43.627 回答
0

尝试做 decimal.Decimal.from_float(frac[i])

于 2013-08-31T17:35:54.127 回答