我在习惯 Numpy 数组时遇到了困难(我是 Matlab 用户)。当我尝试从数组中仅选择一系列值时,我发现生成的数组有一个额外的维度:
ioi = np.nonzero((self.data_array[0,:] >= range_start) & (self.data_array[0,:] <= range_end))
print("self.data_array.shape = {0}".format(self.data_array.shape))
print("self.data_array.shape[:,ioi] = {0}".format(self.data_array[:,ioi].shape))
结果是:
self.data_array.shape = (5, 50000)
self.data_array.shape[:,ioi] = (5, 1, 408)
我还看到 ioi 是一个元组。不知道跟这个有没有关系。
这里发生了什么来创建额外的维度,在这种情况下我应该怎么做,以最直接的方式获得 (5,408) 的数组形状?
最佳答案
最简单、最有效的方法是摆脱 np.nonzero
调用,并像在 Matlab 中一样使用逻辑索引。这是一个例子。 (仅供引用,我使用的是相同形状的随机数据。)
>>> data = np.random.randn(5, 5000)
>>> start, end = -0.5, 0.5
>>> ioi = (data[0] > start) & (data[0] < end)
>>> print(ioi.shape)
(5000,)
>>> print(ioi.sum())
1900
>>> print(data[:, ioi].shape)
(5, 1900)
通常不需要np.nonzero
调用。就像Matlab的find
函数一样,它与逻辑索引相比速度较慢,并且通常通过逻辑索引可以更有效地实现目标。 np.nonzero
与 find
一样,主要应仅在您需要实际索引值本身时使用。
正如您所怀疑的,额外维度的原因是元组的处理方式与 NumPy 中其他类型的索引数组不同。这是为了允许更灵活的索引,例如使用切片、省略号等。请参阅 this useful page进行深入解释,尤其是最后一节。
至少还有两个其他选项可以解决该问题。一种是使用从 np.nonzero
返回的 ioi
数组,直接作为数据数组的唯一索引。如:self.data_array[ioi]
。拥有额外维度的部分原因是您在调用中实际上有两组索引:切片 (:
) 和元组 ioi
。由于这个原因,np.nonzero
保证返回一个元组,因此它的输出始终可以用于直接索引源数组。
最后一个选项是在返回的数组上调用 np.squeeze
,但我会首先选择上述其中一个。
关于python - 过滤后的 Numpy 数组更改维数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53972479/