Python 剪切数组的行和列
我有一个2D数组(NumPy数组),希望得到一个子数组,它是剪切给定行和列的结果 例如,我发现了一种方法:Python 剪切数组的行和列,python,arrays,numpy,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.d
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列。但是,我认为这不是很好,而且据我所知,它必须为两个额外的数组分配空间,一个用于np.delete
的每个返回
所以问题是,是否有某种方法可以以更高效的读取和存储方式获得所需的结果?理想情况下,它只提供对数组正确元素的引用,而不是完整副本。请注意,这个示例不是我需要的数组,答案应该适用于删除行I
和列j
的nxn
。如何
mat[[1,2,3,4],:][:,[0,1,2,4]]
应该给出相同的结果吗?您可以使用带有简单索引的
np.column\u 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]])
实际删除 要实际删除元素,这里有一个使用- 运行时测试-
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
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
保留有效的掩码
您还可以创建一个有效元素的二维掩码,当然也可以创建与输入数组形状相同的二维掩码,以获得更节省内存和时间的方法,如下所示-
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)
运行时测试-
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
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
我认为您的解决方案没有那么糟糕,问题是通过删除任意“行”和“列”,您正在破坏数组的结构(签出),获得具有该新结构的数组的唯一方法是重新分配它
通常只返回数组的内存有效视图,例如,使用常规切片(没有奇特的东西,例如列表)。如果数组是
nxn
,我想剪切行i
和列j
?我应该说,这个示例不是示例中的数组不是我正在使用的数组。您可以考虑允许在某种意义上,在不复制数据的情况下,将数组“剪切”出行和列。开销是内存效率高的位掩码。否则,我相信,如果不创建副本,就很难做到这一点。如果不能用切片表示法(开始、停止、步骤)表达选择(保留的内容),那么就无法避免创建一个或多个副本。在我看来,事实上就是如此。我似乎也无法从蒙面矩阵中获得正确的行为。这似乎是建议答案中最快的(也是最可读的)。结果仍然是一个新的数组,但这似乎是不可避免的。我非常喜欢这个,但我似乎无法从屏蔽数组中获得正确的行为。第一个建议我很喜欢,但被接受的答案是快一点(短一点)。无论如何谢谢你@Bendik当你在输入数组上使用掩码时,你会得到一个1D数组。因此,在此之后,您需要重塑:。重塑(-1,n-1)
,如函数def cut\u valid\u array
中所述。很乐意帮忙!是的,我是从第一个函数中得到的。似乎我无法从蒙面阵列中得到我所需要的。。。无论如何,再次谢谢你。