如何在python中存储真正庞大数字的数组?

时间:2015-09-30 19:49:32

标签: python arrays numpy int factorial

我正在处理大量数据,例如150!举例来说,计算结果不是问题 f = factorial(150)57133839564458545904789328652610540031895535786011264182548375833179829124845398393126574488675311145377107878746854204162666250198684504466355949195922066574942592095735778929325357290444962472405416790722118445437122269675520000000000000000000000000000000000000

但是我还需要在完整的presison中存储一个包含N个大数字的数组。 python列表可以存储它,但速度很慢。 numpy数组很快,但无法处理完整的精度,这是我稍后执行的某些操作所必需的,而且正如我测试的那样,科学记数法(浮点数)中的数字不能产生准确的结果。

编辑:

150!只是一个庞大数字的例子,这并不意味着我只使用阶乘。此外,完整的数字集(并非总是因子的结果)随时间而变化,我需要对函数进行实现和重新评估,因为这些数字是参数,是的,需要全精度。

3 个答案:

答案 0 :(得分:3)

numpy数组在内部使用可以由处理器直接操作的简单数据类型时非常快。由于没有可以存储大量数字的简单本机数据类型,因此它们将转换为浮点数。可以告诉numpy使用Python对象,但它会慢一些。

我的电脑上有一些时间。首先是设置。

a是包含前50个阶乘的Python列表。 b是一个numpy数组,所有值都转换为float64c是一个存储Python对象的numpy数组。

import numpy as np
import math
a=[math.factorial(n) for n in range(50)]
b=np.array(a, dtype=np.float64)
c=np.array(a, dtype=np.object)

a[30]
265252859812191058636308480000000L

b[30]
2.6525285981219107e+32

c[30]
265252859812191058636308480000000L

现在测量索引。

%timeit a[30]
10000000 loops, best of 3: 34.9 ns per loop

%timeit b[30]
1000000 loops, best of 3: 111 ns per loop

%timeit c[30]
10000000 loops, best of 3: 51.4 ns per loop

索引到Python列表的速度最快,然后从numpy数组中提取Python对象,而最慢的是从优化的numpy数组中提取64位浮点数。

现在让我们测量每个元素乘以2。

%timeit [n*2 for n in a]
100000 loops, best of 3: 4.73 µs per loop

%timeit b*2
100000 loops, best of 3: 2.76 µs per loop

%timeit c*2
100000 loops, best of 3: 7.24 µs per loop

由于b*2可以利用numpy优化的阵列,因此速度最快。 Python列表位居第二。使用Python对象的numpy数组是最慢的。

至少在我运行的测试中,索引到Python列表似乎并不慢。什么对你来说很慢?

答案 1 :(得分:0)

如果您将来需要一个阶乘的确切数量,为什么不在数组中保存而不是结果,而是您想要的数字' factorialize'?

E.G。

您有f = factorial(150)

您的结果为57133839564458545904789328652610540031895535786011264182548375833179829124845398393126574488675311145377107878746854204162666250198684504466355949195922066574942592095735778929325357290444962472405416790722118445437122269675520000000000000000000000000000000000000

但你可以简单地说:

def values():

    to_factorial_list = []
        ...
        to_factorial_list.append(values_you_want_to_factorialize)
    return to_factorial_list

def setToFactorial(number):
    return factorial(number)

print setToFactorial(values()[302])

编辑:

公平,那么我的建议是使用我建议的逻辑作为getsizeof(number)你可以合并或使用两个数组,一个数组来保存低阶乘数,另一个来保存大数,例如当getsizeof(number)超过任何尺寸时。

答案 2 :(得分:0)

将其存储为主要因素及其权力的元组。因子(因为,比如N)的因子分解将包含小于N的所有素数。因此,每个元组中的第k个位置将是第k个素数。而且您想要保留一份您已找到的所有素数的单独列表。您可以使用此表示法轻松存储高达几十万的阶乘。如果你真的需要数字,你可以很容易地从中恢复它们(只需忽略5的幂,并在乘以因子得到阶乘时从2的幂减去5的幂...导致5 * 2 = 10 )。