我正在处理大量数据,例如150!举例来说,计算结果不是问题
f = factorial(150)
是
57133839564458545904789328652610540031895535786011264182548375833179829124845398393126574488675311145377107878746854204162666250198684504466355949195922066574942592095735778929325357290444962472405416790722118445437122269675520000000000000000000000000000000000000
。
但是我还需要在完整的presison中存储一个包含N个大数字的数组。 python列表可以存储它,但速度很慢。 numpy数组很快,但无法处理完整的精度,这是我稍后执行的某些操作所必需的,而且正如我测试的那样,科学记数法(浮点数)中的数字不能产生准确的结果。
编辑:
150!只是一个庞大数字的例子,这并不意味着我只使用阶乘。此外,完整的数字集(并非总是因子的结果)随时间而变化,我需要对函数进行实现和重新评估,因为这些数字是参数,是的,需要全精度。
答案 0 :(得分:3)
numpy数组在内部使用可以由处理器直接操作的简单数据类型时非常快。由于没有可以存储大量数字的简单本机数据类型,因此它们将转换为浮点数。可以告诉numpy使用Python对象,但它会慢一些。
我的电脑上有一些时间。首先是设置。
a
是包含前50个阶乘的Python列表。 b
是一个numpy数组,所有值都转换为float64
。 c
是一个存储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 )。