numpy 保留np中的原始数组结构,其中

yzckvree  于 2023-06-23  发布在  其他
关注(0)|答案(2)|浏览(118)

举个例子:

x = np.transpose(np.array([np.arange(10), np.zeros(10, dtype=int)]))
x = np.array([x, x, x])
print("orig: \n", x)
print("")
print("indexed: \n", x[np.where(np.logical_and(x[..., 0] > 3, x[..., 0] < 7))])

这产生:

orig: 
 [[[0 0]
  [1 0]
  [2 0]
  [3 0]
  [4 0]
  [5 0]
  [6 0]
  [7 0]
  [8 0]
  [9 0]]

 [[0 0]
  [1 0]
  [2 0]
  [3 0]
  [4 0]
  [5 0]
  [6 0]
  [7 0]
  [8 0]
  [9 0]]

 [[0 0]
  [1 0]
  [2 0]
  [3 0]
  [4 0]
  [5 0]
  [6 0]
  [7 0]
  [8 0]
  [9 0]]]

indexed: 
 [[4 0]
 [5 0]
 [6 0]
 [4 0]
 [5 0]
 [6 0]
 [4 0]
 [5 0]
 [6 0]]

但我真正想要的是:

[[[4 0]
  [5 0]
  [6 0]]

 [[4 0]
  [5 0]
  [6 0]]

 [[4 0]
  [5 0]
  [6 0]]]

我想这是因为它正在用匹配的最后一维数组填充一个新数组。是这样吗?
有没有办法用np.where实现我想要的东西?如果是,如何进行?如果没有,还有其他更好的方法吗?我可以使用循环,但如果可能的话,我更喜欢使用numpy向量化函数。

d4so4syb

d4so4syb1#

我不确定是否使用np.where执行此操作,但您可以在阵列上调用.reshape。这取决于您需要它的健壮程度(即如果你要在大量不同大小/形状的数据上运行这个),你需要想出一个优雅的方法来确定整形维度。下面是一个例子:

x = np.transpose(np.array([np.arange(10), np.zeros(10, dtype=int)]))
x = np.array([x, x, x])

indexed = x[np.where(np.logical_and(x[..., 0] > 3, x[..., 0] < 7))].reshape(3,3,2)
print("indexed: \n", indexed)

indexed: 
 [[[4 0]
  [5 0]
  [6 0]]

 [[4 0]
  [5 0]
  [6 0]]

 [[4 0]
  [5 0]
  [6 0]]]
bxgwgixi

bxgwgixi2#

布尔掩码:

In [187]: mask = np.logical_and(x[...,0]>3, x[...,0]<7    
In [188]: mask
Out[188]: 
array([[False, False, False, False,  True,  True,  True, False, False,
        False],
       [False, False, False, False,  True,  True,  True, False, False,
        False],
       [False, False, False, False,  True,  True,  True, False, False,
        False]])

是(3,10)型的但是当在索引中使用时,结果变平:

In [189]: x[mask]
Out[189]: 
array([[4, 0],
       [5, 0],
       [6, 0],
       [4, 0],
       [5, 0],
       [6, 0],
       [4, 0],
       [5, 0],
       [6, 0]])

np.where/nonzero获取这些索引:

In [190]: np.nonzero(mask)
Out[190]: 
(array([0, 0, 0, 1, 1, 1, 2, 2, 2], dtype=int64),
 array([4, 5, 6, 4, 5, 6, 4, 5, 6], dtype=int64))

但结果是一样的:

In [191]: x[_]
Out[191]: 
array([[4, 0],
       [5, 0],
       [6, 0],
       [4, 0],
       [5, 0],
       [6, 0],
       [4, 0],
       [5, 0],
       [6, 0]])

由于每个块的“True”的数量相同,我们可以重塑:

In [192]: _.reshape(3,-1,2)
Out[192]: 
array([[[4, 0],
        [5, 0],
        [6, 0]],

       [[4, 0],
        [5, 0],
        [6, 0]],

       [[4, 0],
        [5, 0],
        [6, 0]]])

一般来说,对于所有布尔掩码,这种整形是不可能的。
让我们在每个块中使用不同的值创建一个不同的数组:

In [197]: x = np.transpose(np.array([np.arange(10), np.zeros(10, dtype=int)]))
     ...: z = np.array([x, x-5, x+5])

In [198]: np.nonzero(np.logical_and(z[...,0]>3, z[...,0]<7))
Out[198]: 
(array([0, 0, 0, 1, 2, 2], dtype=int64),
 array([4, 5, 6, 9, 0, 1], dtype=int64))

In [199]: z[_]
Out[199]: 
array([[ 4,  0],
       [ 5,  0],
       [ 6,  0],
       [ 4, -5],
       [ 5,  5],
       [ 6,  5]])

这从一个块中拉3,从下一个块中拉1,从第三个块中拉2。我们不能从这3个子块中创建一个n-d数组。

相关问题