我很难适应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)的数组形状?
答案 0 :(得分:1)
最简单,最有效的方法是摆脱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中其他类型的索引数组的处理方式不同。这是为了允许更灵活的索引,例如使用slice
,椭圆等。更详细的说明,请参见this useful page,尤其是最后一部分。
至少有两个其他选项可以解决此问题。一种是将ioi
返回的np.nonzero
数组直接用作数据数组的 only 索引。如:self.data_array[ioi]
。之所以具有额外的维度,部分原因是您的调用中实际上有两个索引集:切片(:
)和元组ioi
。出于这个原因,保证np.nonzero
完全返回一个元组,以便始终可以将其输出直接用于对源数组进行索引。
最后一个选择是在返回的数组上调用np.squeeze
,但我会选择上面的一个。