我有以下 numpy 复合数据类型:
mytype = numpy.dtype([('x', 'f8'),
('y', 'f8'),
('z', 'f8'))])
但是,当我尝试填充这种类型的向量时,它比三个单独的数组慢 60 倍:
#!/usr/bin/env python3
import time
import random
import numpy
mytype = numpy.dtype([('x', 'f8'),
('y', 'f8'),
('z', 'f8')])
size = 1000000
v = numpy.empty(shape=(size,), dtype=mytype)
print("Start inserting into compound type:")
start = time.time()
for i in range(size):
v[i]['x'] = random.random()
v[i]['y'] = random.random()
v[i]['z'] = random.random()
end = time.time()
print("Done inserting into compound type: Time elapsed: {}.\n".format(end - start))
x = numpy.empty(shape=(size,), dtype='f8')
y = numpy.empty(shape=(size,), dtype='f8')
z = numpy.empty(shape=(size,), dtype='f8')
print("Inserting into three arrays:")
start = time.time()
for i in range(size):
x[i] = random.random()
y[i] = random.random()
z[i] = random.random()
end = time.time()
print("Done inserting into three arrays. Time elapsed: {}".format(end - start))
print("Reading from compound type:")
start = time.time()
for i in range(size):
x1 = v[i]['x']
y1 = v[i]['y']
z1 = v[i]['z']
end = time.time()
print("Done reading compound type: Time elapsed: {}.\n".format(end -start))
print("Reading from three arrays:")
start = time.time()
for i in range(size):
x1 = x[i]
y1 = y[i]
z1 = z[i]
end = time.time()
print("Done reading three arrays. Time elapsed: {}.\n".format(end - start))
此外,我发现读取 numpy 复合数据类型比相应的分离数据类型慢 70 倍。如何提高 numpy 复合数据类型的性能?
编辑:从 master 克隆 numpy 后,这个性能错误就消失了。
最佳答案
是的,使用结构化数组逐个元素工作会更慢。这意味着您应该尽可能尝试执行数组操作:
v=np.empty(10,dtype=ymytype)
v['x']=np.random.random(10)
v['y']=np.random.random(10)
v['z']=np.random.random(10)
将比您的 i
by i
迭代更快。但它仍然比等效的二维数组慢:
v = np.random.random((10,3))
您还可以按记录分配或访问值:
for i in range(10):
v[i] = np.random.random(3)
但如果行数远多于字段数(典型情况),最好按字段赋值。
如果您希望对数组进行快速操作,并且所有值都具有相同类型,请坚持使用 nd 数组。当字段类型不同时,例如字符串、整数和 float 的混合,结构化数组更有用。
如果结构化数组的所有元素都具有相同的数据类型(如您的情况,所有元素都是 float ),则可以在结构化数据类型和二维数组之间来回映射,从而实现两全其美。我已经在其他问题中讨论过这一点。
关于python - 在 numpy 复合数据集中填充值很慢;为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33532249/