为了账号安全,请及时绑定邮箱和手机立即绑定

从 numpy 矩阵中删除/提取子矩阵的最快方法

从 numpy 矩阵中删除/提取子矩阵的最快方法

莫回无 2021-09-14 09:57:28
我有一个 NxN 的方阵(N 通常 >500)。它是使用 numpy 数组构造的。我需要提取一个新矩阵,该矩阵从该矩阵中删除了第 i 列和第 i 行。新矩阵是 (N-1)x(N-1)。我目前正在使用以下代码来提取这个矩阵:            new_mat = np.delete(old_mat,idx_2_remove,0)            new_mat = np.delete(old_mat,idx_2_remove,1)我也尝试使用:row_indices = [i for i in range(0,idx_2_remove)]row_indices += [i for i in range(idx_2_remove+1,N)]col_indices = row_indicesrows = [i for i in row_indices for j in col_indices]cols = [j for i in row_indices for j in col_indices]old_mat[(rows, cols)].reshape(len(row_indices), len(col_indices))但我发现这比np.delete()在前者中使用要慢。前者对于我的应用程序来说仍然很慢。有没有更快的方法来完成我想要的?编辑 1:似乎以下比上面两个更快,但不是很多:new_mat = old_mat[row_indices,:][:,col_indices]
查看完整描述

1 回答

?
料青山看我应如是

TA贡献1772条经验 获得超8个赞

以下是我快速编写的 3 个替代方案:


重复delete:


def foo1(arr, i):

    return np.delete(np.delete(arr, i, axis=0), i, axis=1)

最大程度地使用切片(可能需要一些边缘检查):


def foo2(arr,i):

    N = arr.shape[0]

    res = np.empty((N-1,N-1), arr.dtype)

    res[:i, :i] = arr[:i, :i]

    res[:i, i:] = arr[:i, i+1:]

    res[i:, :i] = arr[i+1:, :i]

    res[i:, i:] = arr[i+1:, i+1:]

    return res

高级索引:


def foo3(arr,i):

    N = arr.shape[0]

    idx = np.r_[:i,i+1:N]

    return arr[np.ix_(idx, idx)]

测试它们是否有效:


In [874]: x = np.arange(100).reshape(10,10)

In [875]: np.allclose(foo1(x,5),foo2(x,5))

Out[875]: True

In [876]: np.allclose(foo1(x,5),foo3(x,5))

Out[876]: True

比较时间:


In [881]: timeit foo1(arr,100).shape

4.98 ms ± 190 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [882]: timeit foo2(arr,100).shape

526 µs ± 1.57 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

In [883]: timeit foo3(arr,100).shape

2.21 ms ± 112 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

所以切片是最快的,即使代码更长。它看起来像np.delete工程一样foo3,但在一维时间。


查看完整回答
反对 回复 2021-09-14
  • 1 回答
  • 0 关注
  • 460 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号