如何提取已展平的2D numpy数组的块

j2datikz  于 2023-10-19  发布在  其他
关注(0)|答案(1)|浏览(111)

我想知道从一个2D numpy数组中提取元素块的最佳方法。请参阅下面的Python代码示例,希望它能解释我想做得更好一点。

import numpy as np

nx = 5
nz = 7
numGPs = nx*nz

GPs_matrix = np.arange(numGPs).reshape((nx,nz), order='F')
av = np.zeros_like(GPs_matrix)
av[1:-1,1:-1] = (GPs_matrix[1:-1,2:] + GPs_matrix[1:-1,:-2] + GPs_matrix[2:,1:-1] + GPs_matrix[:-2,1:-1])/4
# How to do the above if GPs is flattened as per below?
GPs_flat = GPs_matrix.reshape(-1, order='F')
# One (very clunky) way is to do the following
cor = GPs_matrix[1:-1,1:-1].reshape(-1, order='F')
btm = GPs_matrix[1:-1,:-2].reshape(-1, order='F')
top = GPs_matrix[1:-1,2:].reshape(-1, order='F')
lft = GPs_matrix[:-2,1:-1].reshape(-1, order='F')
rgt = GPs_matrix[2:,1:-1].reshape(-1, order='F')
av_flat = np.zeros_like(GPs_flat)
av_flat[cor] = (GPs_flat[top] + GPs_flat[btm] + GPs_flat[rgt] + GPs_flat[lft])/4
# Check
print(av.reshape(-1, order='F'))
print(av_flat)
# Is there a better way?
# I see np.r_() may be useful but I don't know how to best use it. I assume the below attempt can be improved upon
sl_cor = np.r_[nx+1:2*nx-1,2*nx+1:3*nx-1,3*nx+1:4*nx-1,4*nx+1:5*nx-1,5*nx+1:6*nx-1] # Should match cor above
# Check
print(sl_cor)
print(cor)
# The below also works but I would like to avoid using loops if possible
print(np.r_[*[np.arange(1,nx-1)+nx*j for j in range(1,nz-1)]])

从本质上讲,我试图解决两个空间维度的泊松方程。以2D阵列的形式建立问题是方便的,因为阵列中的元素的位置对应于Caribbean网格中的网格点的位置。最后,我将使用一个numerolver在numerolver来解决线性系统(例如,BICGSTAB),其需要线性算子函数作为输入。因此,函数需要返回一个向量,循环效率不高。

jvidinwx

jvidinwx1#

首先,它看起来像你试图计算的是一个卷积。一般来说,我会避免手工进行卷积,而是使用类似scipy.signal.convolve2d的东西。以下是您的案例的等效内容:

from scipy.signal import convolve2d
kernel = np.array(([[0, 1, 0],
                    [1, 0, 1],
                    [0, 1, 0]])) / 4
av = np.zeros_like(GPs_matrix)
av[1:-1, 1:-1] = convolve2d(GPs_matrix, kernel, mode='valid').astype(av.dtype)

在平面化的情况下,最好的方法可能是重塑1D输入,执行2D卷积,然后平面化输出。举例来说:

def eval_1D(vec):
  mat = vec.reshape(nx, nz, order='F')
  kernel = np.array(([[0, 1, 0],
                      [1, 0, 1],
                      [0, 1, 0]])) / 4
  av = np.zeros_like(mat)
  av[1:-1, 1:-1] = convolve2d(mat, kernel, mode='valid').astype(av.dtype)
  return av.ravel(order='F')

print(eval_1D(GPs_matrix.ravel(order='F')))
# [ 0  0  0  0  0  0  6  7  8  0  0 11 12 13  0  0 16 17
#  18  0  0 21 22 23  0  0 26 27 28  0  0  0  0  0  0]

相关问题