如何从具有周期边界条件的numpy数组中选择窗口?

14 投票
2 回答
5361 浏览
提问于 2025-04-16 06:52

假设我创建了一个这样的二维数组:

>>> A=np.arange(16).reshape((4,4))
>>> A
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

我想要能够选择一个3x3的窗口,围绕着任何给定的元素,并且这个窗口在边界处可以循环使用,那我该怎么做呢?我知道如果窗口的边界不和原数组的边界重叠,我可以做到这一点:

>>> A[1:4,0:3]
array([[ 4,  5,  6],
       [ 8,  9, 10],
       [12, 13, 14]])

但是如果我使用像 A[i-1:i+2,j-1:j+2] 这样的表达式,比如当 i=0,j=0 时,它只会返回一个空数组。

2 个回答

1

我还不能评论,但想提出一个改进建议,针对unutbu的解决方案:

他们的方案无法处理像这样的情况

A=np.arange(25).reshape((5,5))

print(A) 
# [[ 0  1  2  3  4]
#  [ 5  6  7  8  9]
#  [10 11 12 13 14]
#  [15 16 17 18 19]
#  [20 21 22 23 24]]

print(neighbors(A, 0, 0, n=5))
# [[24 20 21 22 23]
#  [ 4  0  1  2  3]
#  [ 9  5  6  7  8]
#  [14 10 11 12 13]
#  [19 15 16 17 18]]

0应该在中间,但偏离了一行和一列。

稍微调整一下移动的数值就能解决这个问题

def neighbors_updated(arr, x, y, n_row=3, n_col=3):
    ''' Given a 2D-array, returns an nxn array whose "center" element is arr[x,y]'''
    arr=np.roll(np.roll(arr,shift=-x+int(n_row/2),axis=0),shift=-y+int(n_col/2),axis=1)
    return arr[:n_row,:n_col]

print(neighbors(A, 0, 0, n_row=5, n_col=5))
# [[18 19 15 16 17]
#  [23 24 20 21 22]
#  [ 3  4  0  1  2]
#  [ 8  9  5  6  7]
#  [13 14 10 11 12]]
16

在编程中,有时候我们需要处理一些数据,而这些数据可能来自不同的地方,比如用户输入、文件或者网络请求。为了让程序能够理解和使用这些数据,我们通常需要将它们转换成一种统一的格式。

比如说,如果我们从一个文件中读取数据,这些数据可能是以文本的形式存在的,而我们的程序可能需要将它们转换成数字或者其他类型的数据。这个过程就叫做“数据转换”。

在进行数据转换时,我们需要注意数据的类型,比如整数、浮点数、字符串等。每种类型的数据都有其特定的处理方式,因此我们需要根据实际情况选择合适的方法来进行转换。

总之,数据转换是编程中一个非常重要的环节,它帮助我们将不同来源的数据整理成程序可以使用的格式。

import numpy as np

A=np.arange(16).reshape((4,4))

def neighbors(arr,x,y,n=3):
    ''' Given a 2D-array, returns an nxn array whose "center" element is arr[x,y]'''
    arr=np.roll(np.roll(arr,shift=-x+1,axis=0),shift=-y+1,axis=1)
    return arr[:n,:n]

print(A)
# [[ 0  1  2  3]
#  [ 4  5  6  7]
#  [ 8  9 10 11]
#  [12 13 14 15]]

print(neighbors(A,0,0))
# [[15 12 13]
#  [ 3  0  1]
#  [ 7  4  5]]

print(neighbors(A,1,0))
# [[ 3  0  1]
#  [ 7  4  5]
#  [11  8  9]]

撰写回答