【问题标题】:Stocking large numbers into numpy array将大量数字存储到 numpy 数组中
【发布时间】:2016-09-13 06:57:23
【问题描述】:

我有一个数据集,我正在尝试对其应用一些算术方法。 问题是它给了我相对较大的数字,而当我使用 numpy 进行操作时,它们的库存为 0。

奇怪的是,当我计算数字时,它们有一个 int 值,当我使用 numpy 计算它们时它们才变成零。

x = np.array([18,30,31,31,15])
10*150**x[0]/x[0]
Out[1]:36298069767006890

vector = 10*150**x/x
vector
Out[2]: array([0, 0, 0, 0, 0])

我当然检查过它们的类型:

type(10*150**x[0]/x[0]) == type(vector[0])
Out[3]:True

如何使用 numpy 计算这么大的数字而不看到它们变成零?

请注意,如果我们在开始时删除因子 10,问题会发生轻微变化(但我认为这可能是类似的原因):

x = np.array([18,30,31,31,15])
150**x[0]/x[0]
Out[4]:311075541538526549

vector = 150**x/x
vector
Out[5]: array([-329406144173384851, -230584300921369396, 224960293581823801,
   -224960293581823801, -368934881474191033])

负数表示python中int64类型的最大数是交叉的不是吗?

【问题讨论】:

  • 你能用浮点数np.array([18.0, 30, 31, 31, 15])代替int吗?
  • 不,不要使用浮点值。它们可能看起来有效,但在这些值范围内它们的精度将是可怕的。你的计算有效,但结果是错误的(你没有注意到)。

标签: python arrays numpy largenumber


【解决方案1】:

正如 Nils Werner 已经提到的,numpy 的原生 ctypes 不能保存那么大的数字,但 python 本身可以,因为 int 对象使用任意长度的实现。 所以你可以做的是告诉numpy不要将数字转换为ctypes,而是使用python对象。这会比较慢,但它会起作用。

In [14]: x = np.array([18,30,31,31,15], dtype=object)

In [15]: 150**x
Out[15]: 
array([1477891880035400390625000000000000000000L,
       191751059232884086668491363525390625000000000000000000000000000000L,
       28762658884932613000273704528808593750000000000000000000000000000000L,
       28762658884932613000273704528808593750000000000000000000000000000000L,
       437893890380859375000000000000000L], dtype=object)

在这种情况下,numpy 数组不会存储数字本身,而是对相应 int 对象的引用。当您执行算术运算时,它们不会在 numpy 数组上执行,而是在引用后面的对象上执行。
我认为您仍然可以通过这种解决方法使用大多数 numpy 函数,但它们肯定会比平时慢很多。

但是当你处理这么大的数字时,你会得到这样的结果:D
也许在某个地方有一个图书馆可以更好地处理这个问题。

为了完整性,如果精度不是问题,您也可以使用浮点数:

In [19]: x = np.array([18,30,31,31,15], dtype=np.float64)

In [20]: 150**x
Out[20]: 
array([  1.47789188e+39,   1.91751059e+65,   2.87626589e+67,
         2.87626589e+67,   4.37893890e+32])

【讨论】:

  • 使用numpy.array(dtype=object) 的有趣方法。会记住这一点。
  • dtype=object 选项似乎是一个很好的解决方案。就我而言,这可能会有点困难,因为我必须应用 scipy.special 函数,例如 psi(digamma 函数),它适用于 numpy.array 但不适用于 dtype=object 选项。
  • 一般来说,你不能指望 numpy 数学运算与 dtype=object 一起工作。快速操作使用编译后的代码——适用于各种标准数字数据类型的代码。但是对于object,数组实际上包含指针——指向内存中其他位置的对象。实际上,这样的数组是一个美化的列表(或贬低的列表?)。
【解决方案2】:

150 ** 28 远远超出了 int64 变量所能表示的范围(它在 8e60 的范围内,而 unsigned int64 的最大可能值大约是 18e18)。

Python 可能使用任意长度的整数实现,但 NumPy 没有。

正如您正确推断的那样,负数是 int 溢出的症状。

【讨论】:

  • 那么有没有办法给numpy另一个长度整数实现?我可以使用 vanilla python 一个接一个地计算数字,但这会很长,我真的宁愿避免这种情况。
  • 如果香草 python 不使用相同长度的整数实现,那么 150**x[0]/x[0] 的类型显示为 numpy.int64 似乎很奇怪。这是否意味着它以某种类型进行计算,然后将其存储在另一种类型中?
猜你喜欢
  • 1970-01-01
  • 2021-03-01
  • 1970-01-01
  • 2015-08-23
  • 1970-01-01
  • 1970-01-01
  • 2019-10-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多