包含mpz/mpfr值的numpy数组

6 投票
2 回答
2223 浏览
提问于 2025-04-17 18:29

我想要一个包含mpz/mpfr值的numpy数组。因为我的代码:

import numpy as np
import gmpy2
A=np.ones((5,5));
print A/gmpy2.mpfr(1);

生成了:

RuntimeWarning: invalid value encountered in divide
  print A/gmpy2.mpfr(1);
[[1.0 1.0 1.0 1.0 1.0]
 [1.0 1.0 1.0 1.0 1.0]
 [1.0 1.0 1.0 1.0 1.0]
 [1.0 1.0 1.0 1.0 1.0]
 [1.0 1.0 1.0 1.0 1.0]]

根据我的理解,这是因为无法将gmpy的mpfr转换为numpy的float64类型。那么,我该如何才能首先得到一个包含mpfr值的numpy数组呢?

谢谢。

2 个回答

1

我觉得这是两个库中的一个出现了问题。我也认为这个问题已经修复了。

输入:

import sys
import numpy as np
import gmpy2

print(sys.version)
print(np.__version__)
print(gmpy2.version)

A=np.ones((5,5));
print(A/gmpy2.mpfr(1))

输出:

3.4.2 (v3.4.2:ab2c023a9432, Oct  6 2014, 22:15:05) [MSC v.1600 32 bit (Intel)]
1.9.1
2.0.5
[[mpfr('1.0') mpfr('1.0') mpfr('1.0') mpfr('1.0') mpfr('1.0')]
 [mpfr('1.0') mpfr('1.0') mpfr('1.0') mpfr('1.0') mpfr('1.0')]
 [mpfr('1.0') mpfr('1.0') mpfr('1.0') mpfr('1.0') mpfr('1.0')]
 [mpfr('1.0') mpfr('1.0') mpfr('1.0') mpfr('1.0') mpfr('1.0')]
 [mpfr('1.0') mpfr('1.0') mpfr('1.0') mpfr('1.0') mpfr('1.0')]]

可能是Numpy在遇到未知类型时没有正确说明该怎么做,或者gmpy2没有说明如何进行除法运算(__rdiv__)。

除非你打算修改数组中的元素,否则不需要指定ndarraydtype。像乘法这样的操作会生成一个新的ndarray,Numpy会自动判断该使用什么dtype

8

你需要创建一个数组,并设置它的类型为 dtype=object,这样你就可以在这个数组里放任何Python类型的数据。我没有安装gmpy2,但下面这个例子应该能说明它是怎么工作的:

In [3]: a = np.ones((5, 5), dtype=object)

In [5]: import fractions

In [6]: a *= fractions.Fraction(3, 4)

In [7]: a
Out[7]: 
array([[3/4, 3/4, 3/4, 3/4, 3/4],
       [3/4, 3/4, 3/4, 3/4, 3/4],
       [3/4, 3/4, 3/4, 3/4, 3/4],
       [3/4, 3/4, 3/4, 3/4, 3/4],
       [3/4, 3/4, 3/4, 3/4, 3/4]], dtype=object)

使用 dtype=object 的numpy数组可能会让人有点误解,因为通常numpy能让标准数据类型的操作非常快,但一旦你用对象类型,速度就会慢下来,因为这时候操作是由Python的默认对象操作符来处理的,这样就失去了原本的速度优势:

In [12]: b = np.ones((5, 5)) * 0.75

In [13]: %timeit np.sum(a)
1000 loops, best of 3: 1.25 ms per loop

In [14]: %timeit np.sum(b)
10000 loops, best of 3: 23.9 us per loop

撰写回答