Python创建沿对角线滚动1的矩阵

时间:2018-09-06 02:10:38

标签: python matrix

我想创建一个矩阵,每行从左到右滚动n列,每列k 1s。 (每行中的n-k个元素为0) 示例:

k = 4,n = 10

结果:

1 1 1 1 0 0 0 0 0 0  
0 1 1 1 1 0 0 0 0 0  
0 0 1 1 1 1 0 0 0 0  
0 0 0 1 1 1 1 0 0 0  
0 0 0 0 1 1 1 1 0 0  
0 0 0 0 0 1 1 1 1 0  
0 0 0 0 0 0 1 1 1 1 

如何快速,智能地创建此矩阵?

2 个答案:

答案 0 :(得分:1)

最佳答案取决于您对“智能”的理解。一种内存有效的方法是跨越一维数组:

>>> import numpy as np
>>> from numpy.lib.stride_tricks import as_strided
>>> a = np.zeros(2*n-k, dtype=int)
>>> a[n-k:n] = 1
>>> view = as_strided(a[n-k:], shape=(n-k+1, n), strides=(-8, 8))
>>> view.tolist()
[[1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 1]]

此视图将16个整数存储为70个整数数组。

另一种方法是观察散乱的数组具有4个重复模式,然后是7个零的重复模式。因此,您可以将其平铺并重塑:

>>> r = n-k+1
>>> np.tile([1]*k+[0]*r, r)[:-r].reshape(r,n)
array([[1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
       [0, 1, 1, 1, 1, 0, 0, 0, 0, 0],
       [0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
       [0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 0, 1, 1, 1, 1, 0, 0],
       [0, 0, 0, 0, 0, 1, 1, 1, 1, 0],
       [0, 0, 0, 0, 0, 0, 1, 1, 1, 1]])

如果您不想使用numpy,并且只是在寻找简单直接的Pythonic方法,则可以滚动deque并进行累加:

from collections import deque

data = [1]*k + [0]*(n-k)
d = deque(data)
result = [data]
while not d[-1]:
    d.rotate(1)
    result.append(list(d))

可能有一个listcomp的listcomp-这不是我的,我发现可怜的代码段被遗弃在chatroom #6的寒冷和肮脏的地板上。作者并不喜欢发布它(承认它位于“酷一线”和“不该是一线的东西”之间的模糊线上):

>>> [[1 if 0<=i-j<k else 0 for i in range(n)] for j in range(n-k+1)]
[[1, 1, 1, 1, 0, 0, 0, 0, 0, 0],
 [0, 1, 1, 1, 1, 0, 0, 0, 0, 0],
 [0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
 [0, 0, 0, 1, 1, 1, 1, 0, 0, 0],
 [0, 0, 0, 0, 1, 1, 1, 1, 0, 0],
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 0],
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 1]]

答案 1 :(得分:0)

您可以使用列表理解:

[list(map(int, list(bin(2**10 + (2**4 - 1) * 2**expo)[3:]))) for expo in range(6, -1, -1)]

输出:

[[1, 1, 1, 1, 0, 0, 0, 0, 0, 0], 
 [0, 1, 1, 1, 1, 0, 0, 0, 0, 0], 
 [0, 0, 1, 1, 1, 1, 0, 0, 0, 0], 
 [0, 0, 0, 1, 1, 1, 1, 0, 0, 0], 
 [0, 0, 0, 0, 1, 1, 1, 1, 0, 0], 
 [0, 0, 0, 0, 0, 1, 1, 1, 1, 0], 
 [0, 0, 0, 0, 0, 0, 1, 1, 1, 1]]