4-D numpy数组字典:如何进行优化?

4

我有一个问题,就是初始化一个4-D numpy张量字典时的性能问题。

我有一个系数名称列表:

cnames = ['CN', 'CM', 'CA', 'CY', 'CLN' ...];

这是一个不固定大小的(取决于上方代码)问题。对于每个系数,我需要生成一个4维张量[nalpha X nmach X nbeta X nalt],并将其初始化为零(为了预分配内存),因此我执行以下操作:

#Number of coefficients
numofc = len(cnames);

final_data = {};
#I have to generate <numofc> 4D matrixes
for i in range(numofc):
    final_data[cnames[i]]=n.zeros((nalpha,nmach,nbeta,nalt));

每个索引都是介于10和30之间的整数。每个索引都是介于100和200之间的整数。

这需要大约4分钟时间。我该如何加快速度?或者我做错了什么吗?


1
一个更加Pythonic的解决方案(稍微快一点)是:final_data = {cname : np.zeros((nalpha,nmach,nbeta,nalt)) for cname in cnames} - root
1个回答

6
您发布的代码运行时间不应该超过4分钟(除非 cnames 非常大,或者您的RAM很少并且被迫使用交换空间)。
import numpy as np

cnames = ['CN', 'CM', 'CA', 'CY', 'CLN']*1000
nalpha,nmach,nbeta,nalt = 10,20,30,40
#Number of coefficients
numofc = len(cnames)

final_data = {}
#I have to generate <numofc> 4D matrixes
for i in range(numofc):
    final_data[cnames[i]]=np.zeros((nalpha,nmach,nbeta,nalt))

即使cnames有5000个元素,它仍然应该只需要几秒钟的时间:
% time test.py
real    0m4.559s
user    0m0.856s
sys 0m3.328s

分号在语句末尾表明您具有其他语言的经验。小心将那种语言的命令逐行翻译成NumPy/Python。像C一样编码NumPy是减慢速度的原因。
特别是,尽量避免逐个元素地更新数组中的元素。这在C中可以正常工作,但在Python中非常慢。 NumPy通过委派到用Fortran或Cython或C或C ++编写的函数来实现速度。通过逐个元素地更新数组,您正在使用Python循环,而这些循环不太快。
相反,尝试以整个数组(或至少数组切片)上的操作来重新构造您的计算。
我可能对问题的原因进行了过多的推测。您需要分析您的代码,然后,如果您想要更具体的帮助,请发布分析结果和有问题的代码(最好以SSCCE的形式)。

谢谢你的回答。我查了一下,我对张量大小的理解是错误的。每个索引都在100到180之间。 在这种情况下,4分钟可能可以吗? - rdbisme
3
如果你有足够的内存,它应该只需要几秒钟。可能发生的情况是你的内存不足并开始使用交换空间。一个int64类型的100x100x100x100的数组大约占用760MB,而200x200x200x200大小的相同数组将占用约12GB。如果内存大部分已满,但你有足够的内存来容纳一个数组,你不会收到“内存错误”的提示。相反,你的操作系统将把 RAM 的内容交换到磁盘上,以为新数组腾出空间。读写数GB数据到磁盘是慢的。 - Joe Kington

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接