用条件创建重叠数组 - Python

时间:2015-03-27 01:59:44

标签: python arrays python-3.x numpy

Data = [day(1) day(2)...day(N)...day(2N)..day(K-N)...day(K)]

我希望创建一个numpy数组,其中包含两个数组,N和K,形状为(120,)和(300,)。数组必须采用以下形式:

x1 = [day(1) day(2) day (3)...day(N)] x2 = [day(2) day(3)...day(N) day(N+1)] xN = [day(N) day(N+1) day(N+2)...day(2N)] xK-N = [day(K-N) day(K-N+1)...day(K)]

X基本上是形状(K-N)xN,上面的x1,x2,...xK-N为行。我尝试使用iloc获取具有相同形状的两个数组NK。好到那时候。但是,当我尝试使用X = np.array([np.concatenate((N[i:], K[:i] )) for i in range(len(N)])合并数组时,我只得到一个重叠数组形式的NxN数组,而不是所需的格式。

2 个答案:

答案 0 :(得分:1)

这是你想要制作的(数据更简单)吗?

In [253]: N,K=10,15
In [254]: data = np.arange(K)+10
In [255]: data
Out[255]: array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24])
In [256]: np.array([data[np.arange(N)+i] for i in range(K-N+1)])
Out[256]: 
array([[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
       [11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
       [12, 13, 14, 15, 16, 17, 18, 19, 20, 21],
       [13, 14, 15, 16, 17, 18, 19, 20, 21, 22],
       [14, 15, 16, 17, 18, 19, 20, 21, 22, 23],
       [15, 16, 17, 18, 19, 20, 21, 22, 23, 24]])

使用有关strides的高级提示:

,还有另一种方法可以产生此效果
np.lib.stride_tricks.as_strided(data, shape=(K-N+1,N), strides=(4,4))

在第一种情况下,新数组中的所有值都是原始数据的副本。跨步案例实际上是一种观点。因此,data的任何更改都会出现在2d数组中。没有数据复制,第二个也更快。如果你有兴趣,我可以试着解释一下。


Warren建议使用hankel。这是一个简短的函数,在我们的例子中基本上是这样的:

a, b = np.ogrid[0:K-N+1, 0:N]
data[a+b]

a+b是一个数组:

array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10],
       [ 2,  3,  4,  5,  6,  7,  8,  9, 10, 11],
       [ 3,  4,  5,  6,  7,  8,  9, 10, 11, 12],
       [ 4,  5,  6,  7,  8,  9, 10, 11, 12, 13],
       [ 5,  6,  7,  8,  9, 10, 11, 12, 13, 14]])

在这个例子中,它只比列表理解解决方案好一点,但我希望它对于更大的案例会更好。

答案 1 :(得分:1)

对于以下内容,可能不值得为scipy添加依赖,但如果您已在代码中使用scipy,则可以使用函数scipy.linalg.hankel

In [75]: from scipy.linalg import hankel

In [76]: K = 16

In [77]: x = np.arange(K)

In [78]: x
Out[78]: array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15])

In [79]: N = 8

In [80]: hankel(x[:K-N+1], x[K-N:])
Out[80]: 
array([[ 0,  1,  2,  3,  4,  5,  6,  7],
       [ 1,  2,  3,  4,  5,  6,  7,  8],
       [ 2,  3,  4,  5,  6,  7,  8,  9],
       [ 3,  4,  5,  6,  7,  8,  9, 10],
       [ 4,  5,  6,  7,  8,  9, 10, 11],
       [ 5,  6,  7,  8,  9, 10, 11, 12],
       [ 6,  7,  8,  9, 10, 11, 12, 13],
       [ 7,  8,  9, 10, 11, 12, 13, 14],
       [ 8,  9, 10, 11, 12, 13, 14, 15]])