提高python矩阵的性能

提高python矩阵的性能,python,performance,numpy,matrix,Python,Performance,Numpy,Matrix,我有一个包含地球物理数据的大矩阵(形状:2e6,6)。在搜索矩阵中的值以分配变量之前,我有3个for循环 我的第一个解决方案是使用np.where。太慢了!我读到使用另一个for循环来提高性能。然而,我编写的代码甚至稍微慢一点 请问,有人知道如何提高性能吗 第一种解决方案(np.where) 第二种解决方案(循环的额外) 同样,这两种解决方案都太慢了。我避免FORTRAN或C++(我知道它更快)。有什么建议吗?您的LAT和LON阵列有多大?即使它们只有一个元素长,您的程序也必须执行大约1*1*4

我有一个包含地球物理数据的大矩阵(形状:2e6,6)。在搜索矩阵中的值以分配变量之前,我有3个
for
循环

我的第一个解决方案是使用
np.where
。太慢了!我读到使用另一个
for
循环来提高性能。然而,我编写的代码甚至稍微慢一点

请问,有人知道如何提高性能吗

第一种解决方案(
np.where

第二种解决方案(循环的额外


同样,这两种解决方案都太慢了。我避免FORTRAN或C++(我知道它更快)。有什么建议吗?

您的
LAT
LON
阵列有多大?即使它们只有一个元素长,您的程序也必须执行大约
1*1*400*1e6*3~1.2e9
操作,这太多了。即使在C++中正确实现,也可能需要第二个或更多。
我认为你应该优化你的算法。现在还不清楚你想做什么,但我猜你想在矩阵中找到任何一个位置,它的纬度在你的
LATS
列表中,经度在你的
LONS
列表中,深度在1到400之间。交换循环的位置:沿着外循环中的矩阵运行,然后检查这三个条件是否都成立。之后,您将能够用纬度的
set
替换纬度列表,并且
set
查找比列表查找快得多。

给定数字,仅使用
lexsort
数据数组应该是相当有效的。在开始删除所有
where
语句时花费了2秒钟

代码段假定
LATS
LONS
已排序:

order = np.lexsort([matrix.T][2::-1] # takes < 2 sec
sorted = matrix[order, :]

data_per_lat = np.split(sorted, sorted[:, 0].searchsorted(LATS[1:], axis=0)
for lat, dpla in zip(LATS, data_per_lat):
    data_per_lon = np.split(dpla, dpla[:, 1].searchsorted[LONS[1:], axis=0)
    for lon, dplo in zip(LONS, data_per_lon):
        depth, var1, var2, var3 = dplo.T[2:]
        # the variables are now vectors, containing all data matching lon and lat sorted by depth
order=np.lexsort([matrix.T][2::-1]#耗时<2秒
排序=矩阵[顺序:]
数据按lat=np.split(已排序,已排序[:,0]。搜索已排序(LATS[1:],axis=0)
对于lat,zip中的dpla(lat,每个lat的数据):
数据按长度=np.split(dpla,dpla[:,1]。搜索排序[LONS[1:],axis=0)
对于lon,zip中的dplo(lon,每个lon的数据):
深度,var1,var2,var3=dplo.T[2:]
#变量现在是向量,包含所有按深度排序的与lon和lat匹配的数据

您可以使用矢量化过程压缩起始矩阵,这将加快循环速度

DPTH=np.arange(1,401,1)
mask=np.in1d(matrix[:,0],LATS) * np.in1d(matrix[:,1],LONS) * np.in1d(matrix[:,2],DPTH)
matrix_masked=matrix[mask]
然后通过
nditer
(复杂)或


与其说
中的
很慢,还不如说你做了很多次。你在3个级别上迭代。你用
var1,var2,var3做什么?我用这些变量来计算每个LAT/LON点的深度积分。@Johngoldenboy看起来这里有一个问题:你要求优化算法的特定部分(查找)同时尝试解决更大的问题。我建议打开一个单独的问题(可能在网站上)要求一个更快的计算积分的算法。我认为你所做的是非常次优的,但很难推理,因为我不知道你到底想做什么。在
numpy
中,我们试图避免循环,特别是多层循环。我们将迭代推到快速编译的函数上,只有在不可能的情况下才迭代。可能是这样的其中一种方法是使用@numba()的jit编译。它可以加速此类类型的问题。我需要使用var1到var3计算深度上的积分。LAT和LON的大小都是~100,都已经是一个列表(集合(矩阵[;,1]))。您重新组织我的for循环可能是对的。如果两个数组都是100长的,那么操作量将是巨大的:
100*100*400*1e6*3~1e13
。如果不是几天,也需要几个小时,这取决于硬件和优化。正是如此。这就是我需要优化它的原因。
order = np.lexsort([matrix.T][2::-1] # takes < 2 sec
sorted = matrix[order, :]

data_per_lat = np.split(sorted, sorted[:, 0].searchsorted(LATS[1:], axis=0)
for lat, dpla in zip(LATS, data_per_lat):
    data_per_lon = np.split(dpla, dpla[:, 1].searchsorted[LONS[1:], axis=0)
    for lon, dplo in zip(LONS, data_per_lon):
        depth, var1, var2, var3 = dplo.T[2:]
        # the variables are now vectors, containing all data matching lon and lat sorted by depth
DPTH=np.arange(1,401,1)
mask=np.in1d(matrix[:,0],LATS) * np.in1d(matrix[:,1],LONS) * np.in1d(matrix[:,2],DPTH)
matrix_masked=matrix[mask]
for i in range(matrix_masked.shape[0]):
    var1 = matrix_masked[i,3]
   . . .