删除数组的行和列

时间:2015-11-16 19:14:21

标签: python arrays numpy

我有一个2D数组(NumPy数组),并希望得到一个子数组,它是切断给定行和列的结果。

作为一个例子,我找到了一种方法:

In [111]: mat
Out[111]: 
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10],
       [11, 12, 13, 14, 15],
       [16, 17, 18, 19, 20],
       [21, 22, 23, 24, 25]])

In [112]: np.delete(np.delete(mat, 3, 1), 0,0)
Out[112]: 
array([[ 6,  7,  8, 10],
       [11, 12, 13, 15],
       [16, 17, 18, 20],
       [21, 22, 23, 25]])

这取出了第0行和第3列。但是,我不认为这非常漂亮,据我所知,它必须为两个额外的数组分配空间,每个数据从{{返回一个1}}。

所以问题是,是否有某种方法可以以更高的读取和内存效率方式获得所需的结果?理想情况下,某些东西只能提供对数组正确元素的引用,而不是完整副本。请注意,该示例不是我需要的数组,答案应适用于删除行np.delete和列n x n的{​​{1}}。

4 个答案:

答案 0 :(得分:1)

您可以使用np.column_stack进行简单的索引编制:

>>> np.column_stack((A[1:,:3],A[1:,4:]))
array([[ 6,  7,  8, 10],
       [11, 12, 13, 15],
       [16, 17, 18, 20],
       [21, 22, 23, 25]])

答案 1 :(得分:1)

实际删除

要实际删除元素,请使用broadcasted boolean indexingnp.in1d进行删除 -

In [220]: def cut_valid_array(mat,row_cut,col_cut):
     ...:   m,n = mat.shape
     ...:   row_mask = ~np.in1d(np.arange(m),row_cut)
     ...:   col_mask = ~np.in1d(np.arange(n),col_cut)
     ...:   return mat[(row_mask[:,None]*col_mask)].reshape(-1,n-1)
     ...: 

In [221]: mat = np.random.randint(0,100,(1000,1000))

In [222]: %timeit np.delete(np.delete(mat, col_cut, 1), row_cut,0)
10 loops, best of 3: 26.3 ms per loop

In [223]: mat = np.random.randint(0,100,(1000,1000))

In [224]: %timeit cut_valid_array(mat,row_cut,col_cut)
100 loops, best of 3: 7.48 ms per loop

运行时测试 -

m,n = mat.shape
row_mask = ~np.in1d(np.arange(m),row_cut)
col_mask = ~np.in1d(np.arange(n),col_cut)
mask2D = (row_mask[:,None]*col_mask)

保持有效的面具

您还可以创建有效元素的2D蒙版,当然还有与输入数组相同的形状,以获得更多内存和时间效率的方法,如下所示 -

In [225]: def cut_valid_mask(mat,row_cut,col_cut):
     ...:   m,n = mat.shape
     ...:   row_mask = ~np.in1d(np.arange(m),row_cut)
     ...:   col_mask = ~np.in1d(np.arange(n),col_cut)
     ...:   return (row_mask[:,None]*col_mask)
     ...: 

In [226]: mat = np.random.randint(0,100,(1000,1000))

In [227]: %timeit np.delete(np.delete(mat, col_cut, 1), row_cut,0)
10 loops, best of 3: 27 ms per loop

In [228]: mat = np.random.randint(0,100,(1000,1000))

In [229]: %timeit cut_valid_mask(mat,row_cut,col_cut)
1000 loops, best of 3: 414 µs per loop

运行时测试 -

{{1}}

答案 2 :(得分:1)

我认为你的解决方案不是那么糟糕,问题在于删除任意行"和"列"你正在破坏数组的结构(查看strides),获得具有该新结构的数组的唯一方法是重新分配它。

通常只有certain slicing operations才能返回数组的内存效率视图,例如使用常规切片(没有花哨的东西,例如列表)。

答案 3 :(得分:0)

怎么样

mat[[1,2,3,4],:][:,[0,1,2,4]]

应该给出相同的结果吗?