NumPy数组中的补充切片

3
如果我有一个NumPy数组,例如:
A = np.array([[3, 2], [2, -1], [2, 3], [5, 6], [7,-1] , [8, 9]])

我希望您能拆分包含-1的子数组和不包含-1的部分。 请注意,我正在处理非常大的数据集,因此每个操作可能非常耗时,所以我尝试在内存和CPU时间方面找到最有效的方法。
目前我正在做的是:
 slicing1 = np.where(A[:, 1] == -1)
 with_ones = A[slicing1]
 slicing2 = np.setdiff1d(np.arange(A.shape[0]), slicing1, assume_unique=True)
 without_ones = A[slicing2]

有没有不创建 slicing2 列表的方法来减少内存消耗,因为它可能非常大? 有更好的解决方法吗?
3个回答

6

一种方法是存储所需的逻辑索引,然后在第二种情况下使用其逻辑否定进行索引:

In [46]: indx = A[:, 1] != -1

In [47]: A[indx]
Out[47]: 
array([[3, 2],
       [2, 3],
       [5, 6],
       [8, 9]])

In [48]: A[~indx]
Out[48]: 
array([[ 2, -1],
       [ 7, -1]])

2
这绝对比使用 setdiff1d 好得多,原因有很多。而且由于布尔数组每个项只使用一个字节,即使是两个布尔索引数组的副本,也比整数索引数组及其补集要小。为了节省更多的内存,我相信这样不会复制:numpy.logical_not(ix, out=ix) - senderle

1

我用以下代码成功创建了 without_ones:

filter(lambda x: x[1] != -1,A)

1
或者你可以使用生成器函数:

A = np.array([[3, 2], [2, -1], [2, 3], [5, 6], [7,-1] , [8, 9]])

def filt(arr):
    for item in arr:
        if item[1]!=-1:
            yield item

new_len = 0
for item in A:
    if item[1] != -1:
        new_len += 1

without_ones = np.empty([new_len, 2], dtype=int)
for i, item in enumerate(filt(A)): 
    without_ones[i] = item

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接