Python numpy数组与列表
我需要对一大串数字进行一些计算 与典型阵列相比,array.array或numpy.array是否提供了显著的性能提升 我不需要对数组进行复杂的操作,我只需要能够访问和修改值 e、 g 因此,我将不会真正需要连接、切片等 另外,如果我尝试分配不适合C long的值,数组似乎会抛出一个错误:Python numpy数组与列表,python,arrays,list,numpy,Python,Arrays,List,Numpy,我需要对一大串数字进行一些计算 与典型阵列相比,array.array或numpy.array是否提供了显著的性能提升 我不需要对数组进行复杂的操作,我只需要能够访问和修改值 e、 g 因此,我将不会真正需要连接、切片等 另外,如果我尝试分配不适合C long的值,数组似乎会抛出一个错误: import numpy a = numpy.array([0]) a[0] += 1232234234234324353453453 print(a) 在控制台上,我得到: a[0] += 1232234
import numpy
a = numpy.array([0])
a[0] += 1232234234234324353453453
print(a)
在控制台上,我得到:
a[0] += 1232234234234324353453453
OverflowError: Python int too large to convert to C long
数组是否有一种变体可以让我输入无界Python整数?
或者,这样做会不会从一开始就失去使用数组的意义?您首先需要了解数组和列表之间的区别 数组是一个连续的内存块,由某些类型的元素(例如整数)组成 一旦创建数组,就不能更改其大小。
因此,数组中的每个整数元素都有固定的大小,例如4个字节 另一方面,列表仅仅是地址的“数组”(也有固定大小) 但是,每个元素都保存内存中其他元素的地址,这是您想要处理的实际整数。当然,这个整数的大小与数组的大小无关。因此,您总是可以创建一个新的(更大的)整数,并“替换”旧整数,而不影响数组的大小,数组只保存整数的地址 当然,列表的这种便利性是有代价的:对整数执行算术现在需要对数组进行内存访问,加上对整数本身的内存访问,加上分配更多内存所需的时间(如果需要),加上删除旧整数所需的时间(如果需要的话)。是的,它可能会慢一些,所以你必须小心处理数组中的每个整数 与典型阵列相比,array.array或numpy.array是否提供了显著的性能提升 它可以,取决于你在做什么 或者,这样做会不会从一开始就失去阵列的意义
差不多,是的。您的第一个示例可能是加速。Python循环和对numpy数组中单个项的访问速度很慢。请改用矢量化操作:
import numpy as np
x = np.arange(1000000).cumsum()
可以将无界Python整数放入numpy数组:
a = np.array([0], dtype=object)
a[0] += 1232234234234324353453453
在这种情况下,算术运算比固定大小的C整数要慢
array.array或numpy.array是否比
典型阵列
我尝试用以下代码对此进行测试:
import timeit, math, array
from functools import partial
import numpy as np
# from the question
def calc1(x):
for i in range(1,len(x)):
x[i] = x[i-1] + 1
# a floating point operation
def calc2(x):
for i in range(0,len(x)):
x[i] = math.sin(i)
L = int(1e5)
# np
print('np 1: {:.5f} s'.format(timeit.timeit(partial(calc1, np.array([0] * L)), number=20)))
print('np 2: {:.5f} s'.format(timeit.timeit(partial(calc2, np.array([0] * L)), number=20)))
# np but with vectorized form
vfunc = np.vectorize(math.sin)
print('np 2 vectorized: {:.5f} s'.format(timeit.timeit(partial(vfunc, np.arange(0, L)), number=20)))
# with list
print('list 1: {:.5f} s'.format(timeit.timeit(partial(calc1, [0] * L), number=20)))
print('list 2: {:.5f} s'.format(timeit.timeit(partial(calc2, [0] * L), number=20)))
# with array
print('array 1: {:.5f} s'.format(timeit.timeit(partial(calc1, array.array("f", [0] * L)), number=20)))
print('array 2: {:.5f} s'.format(timeit.timeit(partial(calc2, array.array("f", [0] * L)), number=20)))
结果是列表在这里执行得最快(Python 3.3,NumPy 1.8):
这似乎是违反直觉的。对于这些简单的示例,使用
numpy
或array
而不是list
似乎没有任何优势。使用a=numpy.array(元素数,dtype=numpy.int64)
这将为您提供一个64位整数数组。它们可以存储-2^63和(2^63)-1之间的任何整数(大约在-10^19和10^19之间),这通常就足够了。对于大多数用途,列表非常有用。例如,有时使用numpy数组可能更方便
a=[1,2,3,4,5,6,7,8,9,10]
b=[5,8,9]
考虑一个列表“a”,如果您想访问列表中的元素,请使用列表“b”中给出的离散索引
书写
这是行不通的
但当您将它们用作数组时,您只需编写
a[b]
以数组([6,9,10])的形式获取输出。到OP:For your use case use list 考虑到稳健性和速度,我的使用规则如下: 列表:(最健壮,对于可变情况最快) 例如,当你的列表在物理模拟中不断变化时。当你从头开始“创建”数据时,这些数据在本质上可能是不可预测的 np.array:(线性代数和数据后处理的鲁棒性较差,速度最快)
例如,“后处理”通过传感器或模拟采集的数据集;执行可矢量化的操作。如果不使用矢量化操作(如OP的第一个示例),最后一段同样适用于固定大小整数的numpy数组。这不是numpy阵列速度更快的原因。另请参见
a=[1,2,3,4,5,6,7,8,9,10]
b=[5,8,9]
a[b]
a[b]