我有一些我已经知道的数组,例如:
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] 删除。
我来说两句