快速高效的数组切片,避免删除操作

时间:2018-04-19 21:55:57

标签: python numpy numpy-broadcasting numpy-ufunc numpy-ndarray

我试图得到一个数组A(N,3)的切片(例如元素1-3和5-N),避免使用numpy.delete。该过程的示例如下:

 [[1,2,3],[4,5,6],[7,8,9],[3,2,1]] ==>  [[1,2,3],[3,2,1]]

我希望使用像

这样的东西
A[A != [1,2,3] ].reshape()

但是这会执行元素比较,从而删除比我想要的更多的元素。怎么做呢?我提出了这个想法,但似乎太复杂和缓慢:

A_removed = A[first_removed:last:removed,:] 
mask      = np.not_equal(A[:,None],A_removed)
mask      = np.logical_and.reduce(mask,1)
A         = A[mask].reshape()

有没有办法以更快/更清洁的方式做到这一点?

PD假设A的任何两个元素都不等于

1 个答案:

答案 0 :(得分:1)

修改

重读这个问题,我现在非常确定OP想要与我最初发布的内容相反。以下是你如何做到的:

import numpy as np

def selectRow(arr, selrow):
    selset = set(selrow)
    return np.array([row for row in arr if selset == set(row)])

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

selectRow(arr, [1,2,3])

输出:

array([[1, 2, 3],
       [3, 2, 1]])

我暂时保留原来的答案,以防我错了。

原始答案

订购版

如何:

import numpy as np

def withoutRow(arr, badrow):
    return np.array([row for row in arr if not np.array_equal(row, badrow)])

然后你将这样使用:

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

withoutRow(arr, [1,2,3])

输出:

array([[4, 5, 6],
       [7, 8, 9],
       [3, 2, 1]])

withoutRow应该相当有效(特别是与布尔索引相比),因为只有一个循环(在原始数组的行上),你只需要构建一个新的数组(返回值)。

无序版

如果要删除任何具有匹配坐标的点而不考虑坐标的顺序,则可以使用:

def withoutRowUnordered(arr, badrow):
    badset = set(badrow)
    return np.array([row for row in arr if badset != set(row)])

withoutRowUnordered(arr, [1,2,3])

输出:

array([[4, 5, 6],
       [7, 8, 9]])