在3d阵列上快速处理numpy polyfit?

时间:2018-01-26 08:42:33

标签: python numpy multidimensional-array linear-regression

我有两个形状为(400,1000,1000)的numpy数组。 我想使用两个数组作为输入并在轴0上拟合来应用numpy.polyfit。我尝试了以下代码,如果我想要适合更大的数组,这可能会非常慢。

rows = arr1.shape[1] cols = arr1.shape[2] for i in range(rows): for j in range(cols): idx = np.isfinite(arr1[:, i, j]) & np.isfinite(arr2[:, i, j]) # Get slope slope = np.polyfit(arr1[:, i, j][idx], arr2[:, i, j][idx], 1)[0] ...

知道如何加快速度吗? 提前谢谢!

1 个答案:

答案 0 :(得分:0)

线性回归

关于你的代码示例,我假设你只是想做一个简单的线性回归,你需要线性函数的斜率。

这是一个比普通的polyfit更简单的问题。 https://en.wikipedia.org/wiki/Simple_linear_regression

您的示例在我的电脑上采用 170s 。我不想展示两个版本(只有numpy可以提供45秒和使用numba的解决方案,在我的机器上持续2.5秒(Core i7-4771)。

仅使用numpy(45s未创建测试数组)

#Creating the Test Arrays
import numpy as np
import time

arr1=np.random.rand(400, 1000, 1000)
arr2=np.random.rand(400, 1000, 1000)

#Test function
def Test(arr1,arr2):
  Slope=np.empty((arr1.shape[1],arr1.shape[2]))
  for i in range(arr1.shape[1]):
    for j in range(arr1.shape[2]):
      idx = np.isfinite(arr1[:, i, j]) & np.isfinite(arr2[:, i, j])
      # Get slope
      Slope[i,j]=lin_regression(arr1[idx, i, j],arr2[idx, i, j])

#Linear regression
def lin_regression(arr1,arr2):
  m_x=np.mean(arr1)
  m_y=np.mean(arr2)

  slope=np.sum((arr1-m_x)*(arr2-m_y))/np.sum((arr1-m_x)**2)
  return slope

使用numba(2.5s)

#Creating the Test Arrays
import numba as nb
import numpy as np
import time

arr1=np.random.rand(400, 1000, 1000)
arr2=np.random.rand(400, 1000, 1000)

@nb.njit(fastmath=True)
def lin_regression(arr1,arr2,slope):
  m_x=np.mean(arr1)
  m_y=np.mean(arr2)

  slope=np.sum((arr1-m_x)*(arr2-m_y))/np.sum((arr1-m_x)**2)

@nb.njit(fastmath=True,parallel=True)
def Test(arr1,arr2):
  Slope=np.empty((arr1.shape[1],arr1.shape[2]))
  for i in nb.prange(arr1.shape[1]):
    for j in range(arr1.shape[2]):
      idx = np.isfinite(arr1[:, i, j]) & np.isfinite(arr2[:, i, j])
      # Get slope
      Slope[i,j]=lin_regression(arr1[idx, i, j],arr2[idx, i, j])