Skip to main content
 首页 » 编程设计

python之在 numpy 中使用二维索引对一维数组进行子采样

2025年05月04日6Renyi-Fan

背景: 我正在使用的数据是从 netCDF4 对象中提取的,该对象在初始化时创建了一个 numpy 掩码数组,但似乎不支持 numpy reshape() 方法,使得只有在所有数据都被复制后才能 reshape = 太慢了。

问题:如何对一维数组进行二次采样,它基本上是一个展平的二维数组,而不对其进行整形?

import numpy 
 
a1 = np.array([[1,2,3,4], 
               [11,22,33,44], 
               [111,222,333,444], 
               [1111,2222,3333,4444], 
               [11111,22222,33333,44444]]) 
 
a2 = np.ravel(a1) 
 
rows, cols = a1.shape 
 
row1 = 1 
row2 = 3 
 
col1 = 1 
col2 = 3 

我想使用一种不需要将一维数组 reshape 为二维数组的快速切片方法。

期望的输出:

np.ravel(a1[row1:row2, col1:col2]) 
 
>> array([ 22,  33, 222, 333]) 

我得到了开始和结束位置,但这只是选择了这些点之间的所有数据(即额外的列)。

idx_start = (row1 * cols) + col1 
idx_end   = (row2 * cols) + col2 

更新: 我刚试过Jaime's brilliant answer ,但 netCDF4 似乎不允许二维索引。

z = dataset.variables["z"][idx] 
  File "netCDF4.pyx", line 2613, in netCDF4.Variable.__getitem__ (netCDF4.c:29583) 
  File "/usr/local/lib/python2.7/dist-packages/netCDF4_utils.py", line 141, in _StartCountStride 
    raise IndexError("Index cannot be multidimensional.") 
IndexError: Index cannot be multidimensional. 

请您参考如下方法:

您可以通过 np.ogrid 的组合得到您想要的东西和 np.ravel_multi_index :

>>> a1 
array([    1,     2,     3,     4,    11,    22,    33,    44,   111, 
         222,   333,   444,  1111,  2222,  3333,  4444, 11111, 22222, 
       33333, 44444]) 
>>> idx = np.ravel_multi_index((np.ogrid[1:3,1:3]), (5, 4)) 
>>> a1[idx] 
array([[ 22,  33], 
       [222, 333]]) 

如果这就是您所追求的,您当然可以拆开这个数组以获得一维返回。另请注意,这是原始数据的副本,而不是 View 。


编辑 您可以保持相同的通用方法,将 np.ogrid 替换为 np.mgrid 并 reshape 它以获得平坦的返回:

>>> idx = np.ravel_multi_index((np.mgrid[1:3,1:3].reshape(2, -1)), (5, 4)) 
>>> a1[idx] 
array([ 22,  33, 222, 333])