我遇到了一些性能问题,我很高兴看到这个。
我正在阅读频域数据,我需要制作一个数据立方体来补偿时域中的起始频率。
我现在这样做的方式是:
compdata = [[np.exp(t_range*sflist[y]) for y in x] for x in sfcube]
其中
t_range = 1j*2*np.pi*time_axis_ns
time_axis_ns = np.array([x*delta_time_ns for x in xrange(number_of_points_for_fft)])
sflist = array([ 29500000., 30500000.])
sfcube是一个带有sflist索引的NxM数组。
计算compdata是我现在程序中最慢的部分,是否有任何优化想法?
答案 0 :(得分:1)
快速获胜将是使用多处理模块在所有CPU核心(+ HT,如果可用)上并行化。
from multiprocessing import Pool
pool = Pool(16) ## use total number of cores, x2 if HT is supported.
def f(y):
return np.exp(t_range*sflist[y])
compdata = [pool.map(f, x) for x in sfcube]
当然,这将使您的速度提高4倍到16倍(取决于核心数量)。不过,如果这还不够好,你需要弄清楚如何用矢量/矩阵运算来做到这一点。
答案 1 :(得分:1)
这是你的计算方法,也是一种替代方案,更多的是numpythonic:
compdata = [[np.exp(t_range*sflist[y]) for y in x] for x in sfcube]
compdata2 = np.take(np.exp(sflist[:, None] * t_range), sfcube, axis=0)
根据您的问题设置此示例数据:
sfcube = np.random.randint(2, size=(100, 100))
delta_time_ns = 100
number_of_points_for_fft = 1024
time_axis_ns = np.array([x*delta_time_ns for x in xrange(number_of_points_for_fft)])
t_range = 1j*2*np.pi*time_axis_ns
sflist = np.array([ 29500000., 30500000.])
我得到了这些时间:
In [3]: %timeit compdata = [[np.exp(t_range*sflist[y]) for y in x] for x in sfcube]
1 loops, best of 3: 1.76 s per loop
In [4]: %timeit compdata2 = np.take(np.exp(sflist[:, None] * t_range), sfcube, axis=0)
10 loops, best of 3: 72.2 ms per loop
这是20倍的加速,但结果会发生变化,具体取决于sflist
和sfcube
的实际尺寸。你得到的是一个3D numpy数组,而不是数组列表的列表,虽然它们在大多数设置中是可互换的,当然:
In [5]: np.allclose(compdata, compdata2)
Out[5]: True
答案 2 :(得分:0)
您可以使用Python-psyco库
http://psyco.sourceforge.net/
http://en.wikipedia.org/wiki/Psyco
或任何其他类似的图书馆
它可能会加快您的计划。
答案 3 :(得分:0)
如果您有索引数组,则可以使用它来向量化计算:
In [1]: a = numpy.random.random((4,4))
In [2]: a
Out[2]:
array([[ 0.08746418, 0.57716752, 0.85863208, 0.42931856],
[ 0.90259153, 0.19590983, 0.73075288, 0.88976529],
[ 0.71843135, 0.0169308 , 0.98336314, 0.22227009],
[ 0.93776916, 0.58943769, 0.55040806, 0.92192396]])
In [3]: a[0]
Out[3]: array([ 0.08746418, 0.57716752, 0.85863208, 0.42931856])
In [7]: index=[(0,1), (0,1)]
In [8]: a[index]
Out[8]: array([ 0.08746418, 0.19590983])
In [9]: a[index] = 100*a[index]
In [10]: a[index]
Out[10]: array([ 8.74641837, 19.59098276])
这通常比使用Python列表快得多。请注意,a从一开始就是一个NumPy数组,我使用的索引的格式为a[list_of_rows, list_of_columns]
答案 4 :(得分:0)
首先,您可以使用以下方式创建time_axis_ns
数组:
time_axis_ns = np.arange(number_of_points_for_fft)*delta_time_ns
然后,而不是迭代sfcube中的索引:
sflist[sfcube]
应该给出相同的结果。然后根据此结果进行np.exp(t_range*
。