Python 如何在两个不同大小的阵列之间加速操作?

Python 如何在两个不同大小的阵列之间加速操作?,python,python-3.x,numpy,multidimensional-array,numpy-ndarray,Python,Python 3.x,Numpy,Multidimensional Array,Numpy Ndarray,我有两个数组,它们是三维空间中的点列表。这些数组有不同的长度 np.shape(arr1) == (34709, 3) np.shape(arr2) == (4835053, 3) 我有一个函数,它可以计算一个数组中的一个点和另一个数组中的所有点之间的勾股距离,给定周期性边界条件: def pythag_periodic(array, point, dimensions): delta = np.abs(array - point) delta = np.where(delta

我有两个数组,它们是三维空间中的点列表。这些数组有不同的长度

np.shape(arr1) == (34709, 3)
np.shape(arr2) == (4835053, 3)
我有一个函数,它可以计算一个数组中的一个点和另一个数组中的所有点之间的勾股距离,给定周期性边界条件:

def pythag_periodic(array, point, dimensions):
    delta = np.abs(array - point)
    delta = np.where(delta > 0.5 * dimensions, delta - dimensions, delta)
    return np.sqrt((delta ** 2).sum(axis=-1))
我正在尝试将此操作应用于两个阵列中的所有点。我有一个递归调用这个函数的循环,但是它非常慢

for i in arr1:
    pp.append(pythag_periodic(arr2, i, dimensions))
任何关于我如何加快这一进程的建议都将不胜感激。

您应该使用numba:(披露:我不是作者)。它是一个在运行时将Python函数转换为优化机器代码的库。因此,用Python编译的Numba数值算法可以接近C或FORTRAN的速度

应用于代码非常简单。简而言之,导入库,然后使用装饰器。此外,您还有更多与您相关的选项,如并行化算法(查看他们的网站)。 例如:

from numba import jit


@jit(nopython=True)
def pythag_periodic(array, point, dimensions):
    delta = np.abs(array - point)
    delta = np.where(delta > 0.5 * dimensions, delta - dimensions, delta)
    return np.sqrt((delta ** 2).sum(axis=-1))

另一个很酷的选择是利用Numpy(在索引数组时通过
None
关键字)和super-neat函数来避免循环,并分别同时执行求和和和平方运算

但是请注意,对于小矩阵,这种方法稍微慢一点,但一旦达到大于4000个元素的大小,速度就会快得多。另外,要小心内存不足,因为矢量化有这个缺点(尽管您已经在代码中存储了
NxM
数组)


我将看一看多处理库——特别是池。您正在查看大小为34709 x 4835053的最终矩阵。你确定你有足够的内存吗?几乎不需要签出、映射reduce、PyCUDA、使用C/C++绑定运行计算密集型部分。你也可以将计算欧氏距离的行更改为使用np.linalg.norm()您可以将这些数据分块,在单独的进程上运行,并将结果合并到一个进程中。请注意,Numba仅通过jitting此函数不会提供很大的改进。这应该快得多,因为在
arr1
上迭代的循环也是jitted的。还要注意的是,Numba甚至可以并行化这个包含循环(如果需要的话)。
import numpy as np

def pythag_periodic_vectorized(a1, a2):
    delta = np.abs(a1[:,None,:] - a2[None,...])
    delta = np.where(delta > 0.5 * a1.shape[1], delta - a1.shape[1], delta)

return np.sqrt(np.einsum("ijk,ijk->ij", delta, delta))