Numpy数组获取不是NaN的数组的子集/切片

Posted

技术标签:

【中文标题】Numpy数组获取不是NaN的数组的子集/切片【英文标题】:Numpy array get the subset/slice of an array which is not NaN 【发布时间】:2013-06-12 04:02:57 【问题描述】:

我有一个大小数组:(50, 50)。在这个数组中有一个大小为 (20,10) 的切片。 只有这个 slice 包含数据,其余的都设置为 nan。

如何从我的大数组中切出这个切片?

【问题讨论】:

【参考方案1】:

您可以使用精美的索引来收集not NaN 的项目:

a = a[ np.logical_not( np.isnan(a) ) ].reshape(20,10)

或者,按照乔金顿的建议:

a = a[ ~np.isnan(a) ]

【讨论】:

虽然有了这个,你还是要提前知道非NaN区域的形状。 OP,你事先知道吗? 对 OP 的好问题,从问题文本看来,最终的形状是已知的。但是,如果至少知道列数或行数,则可以使用这种方法... 附带说明,使用~ 运算符而不是logical_not 会更简洁(尽管可读性较差)。例如。 a[~np.isnan(a)]. 非常感谢您的提示!我实际上对此一无所知...我将编辑答案...【参考方案2】:

你知道 NaN 在哪里吗?如果是这样,这样的事情应该可以工作:

newarray = np.copy(oldarray[xstart:xend,ystart:yend])

其中xstartxend 是您想要在x 维度中的切片的开始和结束,对于y 也是类似的。如果您不再需要它,您可以删除旧数组以释放内存。

如果您不知道 NaN 在哪里,这应该可以解决问题:

# in this example, the starting array is A, numpy is imported as np
boolA = np.isnan(A) #get a boolean array of where the nans are
nonnanidxs = zip(*np.where(boolA == False)) #all the indices which are non NaN
#slice out the nans
corner1 = nonnanidxs[0]
corner2 = nonnanidxs[-1]
xdist = corner2[0] - corner1[0] + 1
ydist = corner2[1] - corner1[1] + 1
B = copy(A[corner1[0]:corner1[0]+xdist,corner1[1]:corner1[1]+ydist])
#B is now the array you want

请注意,这对于大型数组来说会很慢,因为np.where 会查看整个内容。数字错误跟踪器中存在一个未解决的问题,该方法发现第一个索引等于某个值然后停止。可能有一种更优雅的方式来做到这一点,这只是我想到的第一件事。

编辑:忽略,sgpc 的答案要好得多。

【讨论】:

NaN 会改变,所以我不知道它们会从哪里开始,只知道有限区域是连续的。我想切出有限的区域并仍然保持二维形状,但 numpy 不会这样做: zz = obj.lat2d[np.isfinite(obj.lat2d)] zz.shape is (33024,) 编辑了我的答案,见上文,或查看 sgpc 的答案。

以上是关于Numpy数组获取不是NaN的数组的子集/切片的主要内容,如果未能解决你的问题,请参考以下文章

使用numpy数组更改python pandas数据框切片中的元素[重复]

NumPy 数组切片索引

02 numpy 索引与切片

在numpy中获取3D数组的2D切片的平均值

Numpy学习二:数组的索引与切片

Numpy - 从数组中切片二维行或列向量