nparrays_list = [
array([1, 2, 3, 4])
array([5, 6, 7, 8]),
array([9, 10, 11, 12])
]
不用担心制作新列表。列表只包含指向内存中其他地方的对象的指针。在这种情况下,列表只占用 3 个整数的内存。组件确实会占用内存 - 它们是具有 4 个元素数据缓冲区的数组。
nparrays_list_Decimal = [
array([Decimal('1'), Decimal('2'), Decimal('3'), Decimal('4')]),
array([Decimal('5'), Decimal('6'), Decimal('7'), Decimal('8')]),
array([Decimal('9'), Decimal('10'), Decimal('11'), Decimal('12')])
]
是另一个小列表,有 3 个指针。您可以将这些指针放回原来的nparray_list,但为什么呢?只是为了节省 3 个整数的空间?
但重要的是,新数组在内存方面与原始数组不兼容:
array([Decimal('1'), Decimal('2'), Decimal('3'), Decimal('4')])
是一个对象 dtype 数组。这就像一个列表,带有指向内存中其他位置的 Decimal(n') 对象的指针。那必须是一个新数组;它不能替换原始array([1,2,3,4]) 中的np.int32 项。
你为什么不直接离开
nparrays_list = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
]
到:
nparrays_list_Decimal = [
[Decimal('1'), Decimal('2'), Decimal('3'), Decimal('4')],
[Decimal('5'), Decimal('6'), Decimal('7'), Decimal('8')],
[Decimal('9'), Decimal('10'), Decimal('11'), Decimal('12')]
]
换句话说,坚持使用列表。 Decimal 对象的数组是否比相同对象的列表更有用?
================
因为Decimal 定义了许多数学运算,所以可以对Decimal 对象数组执行一些数组数学运算:
In [482]: arr = np.array([Decimal(i) for i in range(1,4)])
In [483]: arr
Out[483]: array([Decimal('1'), Decimal('2'), Decimal('3')], dtype=object)
In [484]: arr + 1
Out[484]: array([Decimal('2'), Decimal('3'), Decimal('4')], dtype=object)
In [485]: 1 / arr
Out[485]:
array([Decimal('1'), Decimal('0.5'),
Decimal('0.3333333333333333333333333333')], dtype=object)
Speedwise 最后一条语句与以下基本相同:
np.array([1/i for i in arr])
会比1/np.arange(1,4)慢。
=====================
您可以通过以下方式制作 Decimal 数组来稍微提高速度:
In [503]: np.frompyfunc(Decimal,1,1)(np.arange(3))
Out[503]: array([Decimal('0'), Decimal('1'), Decimal('2')], dtype=object)
In [504]: np.frompyfunc(Decimal,1,1)(np.arange(12).reshape(3,4))
Out[504]:
array([[Decimal('0'), Decimal('1'), Decimal('2'), Decimal('3')],
[Decimal('4'), Decimal('5'), Decimal('6'), Decimal('7')],
[Decimal('8'), Decimal('9'), Decimal('10'), Decimal('11')]], dtype=object)
在其他测试中,我发现frompyfunc 与更显式的迭代表达式相比,速度有所提高(例如 2 倍)。它还具有无缝处理多维数组的优势。它返回一个object 数组。有时这是个问题;在这里就好了。
In [509]: timeit np.frompyfunc(Decimal,1,1)(np.arange(2000))
1000 loops, best of 3: 752 µs per loop
In [510]: timeit np.array([Decimal(str(i)) for i in np.arange(2000)])
100 loops, best of 3: 17.1 ms per loop
In [515]: timeit np.array([Decimal(i) for i in range(2000)])
100 loops, best of 3: 7.39 ms per loop
In [525]: timeit np.array([Decimal(i.item()) for i in np.arange(2000)])
100 loops, best of 3: 11.3 ms per loop
我想知道你为什么使用str(i)。但是后来我发现Decimal只能拿几个np.dtypes(不是np.int32)。我的猜测是 frompyfunc 使用 item() 或等价物来生成 Python 标量:
In [523]: np.frompyfunc(Decimal,1,1)(np.arange(2))
Out[523]: array([Decimal('0'), Decimal('1')], dtype=object)
In [524]: np.array([Decimal(i.item()) for i in np.arange(2)])
Out[524]: array([Decimal('0'), Decimal('1')], dtype=object)
frompyfunc 必须执行与 i.item() 等效的操作才能从 np.int32 对象生成 Python 标量。