通过沿对角线复制给定数组来以numpy创建矩阵的有效方法

胡力

我有一些我已经知道的数组,例如:

a = np.array([1,2,3])

我也知道我想要一个总长length a + some amount n长为一定大小的矩阵n+1,如下所示:

n = 4
length = len(a) + n
width = n + 1

我正在寻找创建一个像这样的数组:

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

不幸的是numpy.kron,通常来说,对角线不是我想要的,因为这会使下一行增加3而不是1。

我有一种方法,可以在其中使用for循环创建矩阵的每一行,并将结果数组彼此堆叠,以及一种我scipy.sparse.diag再次使用for循环创建数组的方法,但我想知道是否有更有效的方法。

迪卡卡

这是一个np.lib.stride_tricks.as_strided使我们views进入零填充数组的方法,因此在内存和性能方面都非常有效-

def sliding_windows(a, n=4):
    length = len(a) + n
    width = n + 1
    z_pad = np.zeros(n,dtype=a.dtype)
    ac = np.r_[z_pad, a, z_pad]
    s = ac.strides[0]    
    strided = np.lib.stride_tricks.as_strided
    return strided(ac[n:], shape=(width, length), strides=(-s,s),writeable=False)

如果您需要可写的版本,只需使用复制即可sliding_windows(a, n=4).copy()

样品运行-

In [42]: a
Out[42]: array([1, 2, 3])

In [43]: sliding_windows(a, n=4)
Out[43]: 
array([[1, 2, 3, 0, 0, 0, 0],
       [0, 1, 2, 3, 0, 0, 0],
       [0, 0, 1, 2, 3, 0, 0],
       [0, 0, 0, 1, 2, 3, 0],
       [0, 0, 0, 0, 1, 2, 3]])

In [44]: sliding_windows(a, n=5)
Out[44]: 
array([[1, 2, 3, 0, 0, 0, 0, 0],
       [0, 1, 2, 3, 0, 0, 0, 0],
       [0, 0, 1, 2, 3, 0, 0, 0],
       [0, 0, 0, 1, 2, 3, 0, 0],
       [0, 0, 0, 0, 1, 2, 3, 0],
       [0, 0, 0, 0, 0, 1, 2, 3]])

使用array-assignment,还有一个功能,如果您需要可写的版本,这应该很好-

def sliding_windows_arrassign(a, n=4):
    pad_length = len(a) + n + 1
    width = n + 1
    p = np.zeros((width,pad_length),dtype=a.dtype)
    p[:,:len(a)] = a
    return p.ravel()[:-n-1].reshape(width,-1)

在大型阵列上进行基准测试

1)100元素和类似的n

In [101]: a = np.arange(1,101)

In [102]: %timeit sliding_windows(a, n=len(a)+1)
100000 loops, best of 3: 17.6 µs per loop

In [103]: %timeit sliding_windows_arrassign(a, n=len(a)+1)
100000 loops, best of 3: 8.63 µs per loop

# @Julien's soln
In [104]: %%timeit
     ...: n = len(a)+1
     ...: m = np.tile(np.hstack((a,np.zeros(n+1))),n+1)[:(n+len(a))*(n+1)]
     ...: m.shape = (n+1, n+len(a))
100000 loops, best of 3: 15 µs per loop

2)〜5000元素和类似的n

In [82]: a = np.arange(1,5000)

In [83]: %timeit sliding_windows(a, n=len(a)+1)
10000 loops, best of 3: 23.2 µs per loop

In [84]: %timeit sliding_windows_arrassign(a, n=len(a)+1)
10 loops, best of 3: 28.9 ms per loop

# @Julien's soln
In [91]: %%timeit
    ...: n = len(a)+1
    ...: m = np.tile(np.hstack((a,np.zeros(n+1))),n+1)[:(n+len(a))*(n+1)]
    ...: m.shape = (n+1, n+len(a))
10 loops, best of 3: 34.3 ms per loop

np.lib.stride_tricks.as_strided 由于前面讨论的内存效率,与数组长度无关,它将具有恒定的运行时间。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

从给定的numpy数组创建块对角线numpy数组

Matlab提取3D矩阵对角线的有效方法

将R中的稀疏矩阵的对角线归零的内存有效方法

在朱莉娅的稀疏矩阵中有效地插入对角线

Matlab有效地获取矩阵乘积的对角线值

如何有效地检查矩阵关于二次对角线对称

沿对角线子集对称矩阵

NumPy-创建具有对角线幂的上三角矩阵

检查共享行,列,对角线的最有效方法?

带有交替值的numpy矩阵对角线填充

二维数组中沿对角线和反对角线的总和-NumPy / Python

如何从numpy中的现有数组创建对角线数组

朱莉娅-如何有效地将矩阵的对角线归零?

创建矩阵的非对角线元素

如何沿高维数组的对角线分布一个Numpy数组?

创建矩阵,其中所有对角线在反对角线方向上均具有相同的值

如何在numpy中创建反对角恒等矩阵(对角线从左向右翻转)

如何在C / C ++或Cuda中按对角线有效按位翻转char数组?

沿矩阵的对角线设置值

多维numpy数组的对角线

numpy排列对角线数组

在仅保留对角线输入的同时执行大点/张量点乘积的最有效方法

Tensorflow:使用对角线/超对角线创建输入的对角矩阵

如何将下对角线元素的 Numpy 数组转换为完整矩阵的数组

在 Python 中为给定的 k 替换矩阵的所有子对角线

矩阵:仅在 numpy 数组的对角线位置放置负值

在MATLAB中创建对角线和左对角线均为1的矩阵

有效创建三对角矩阵

在mxnet中有效创建压缩带状对角矩阵