简体   繁体   English

从给定的数组创建一个“包装”的ndarray

[英]Create a “wrapped” ndarray from a given array

I'm trying to create a 2D array from an array by using a rolled given array as the rows of the 2D array of a specified row dimension. 我试图通过使用滚动的给定数组作为指定行尺寸的2D数组的行,从数组创建2D数组。 For example: 例如:

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

want a matrix of 3 rows (using r) as 想要3行矩阵(使用r)作为

[[2,3,4,1],
 [1,2,3,4],
 [4,1,2,3]]

I think I have an idea by defining a function using numpy.roll and a for-loop but I'm trying to avoid that as my 2D array is going to be very large. 我想我有一个想法,就是使用numpy.roll和for循环定义一个函数,但是由于我的2D数组将变得非常大,所以我试图避免这种情况。 I would like to have the ability to roll backwards if possible. 如果可能,我希望能够向后滚动。

Is there a way using numpy functions that can do this instead? 有没有办法使用numpy函数来代替呢? Any suggestions on this are appreciated. 任何建议对此表示赞赏。

If using scipy is an option, you can use scipy.linalg.circulant . 如果使用SciPy的是一个选项,你可以使用scipy.linalg.circulant You will still have to tweak the argument to circulant to get exactly what you want, since circulant simply makes the given one-dimensional argument the first column of a square circulant matrix . 您仍然必须微调circulant的参数以获取所需的内容,因为circulant只是使给定的一维参数成为平方循环矩阵的第一列。

For example: 例如:

In [25]: from scipy.linalg import circulant

In [26]: r = np.array([1,2,3,4])

Here's what circulant gives: 这是circulant给出的:

In [27]: circulant(r)
Out[27]: 
array([[1, 4, 3, 2],
       [2, 1, 4, 3],
       [3, 2, 1, 4],
       [4, 3, 2, 1]])

With some help from np.roll() , you can get your desired array: np.roll()帮助下,您可以获得所需的数组:

In [28]: circulant(np.roll(r, -1)).T[:-1]
Out[28]: 
array([[2, 3, 4, 1],
       [1, 2, 3, 4],
       [4, 1, 2, 3]])

Or: 要么:

In [29]: circulant(np.roll(r[::-1], -1))[1:]
Out[29]: 
array([[2, 3, 4, 1],
       [1, 2, 3, 4],
       [4, 1, 2, 3]])

This is a solution to the problem. 这是解决问题办法。 It uses numpy's vstack to combine the rows into an array. 它使用numpy的vstack将行合并为一个数组。 It is maybe not the most efficient one though (I don't know the efficiency of res = np.vstack((res, r)) ) 它可能不是最有效的(我不知道res = np.vstack((res, r))的效率)

import numpy as np

def main():
    r = np.array([1,2,3,4])
    x = [i for i in range(1, len(r))] + [0]           # Forwards
    # x = [len(r)-1] + [i for i in range(len(r)-1)]     # Backwards
    r = r[x]
    res = r
    for c in range(2):
        r = r[x]
        res = np.vstack((res, r))
    print res
    return 0

if __name__ == '__main__':
    main()

It produces: 它产生:

[[2 3 4 1]     'Forwards'
 [3 4 1 2]
 [4 1 2 3]]

[[4 1 2 3]     'Backwards'
 [3 4 1 2]
 [2 3 4 1]]

To change the order, it's only necessary to change the x = line. 要更改顺序,只需更改x =行。

Here's a simple solution using list indexing. 这是使用列表索引的简单解决方案。

r = [1, 2, 3, 4] # note: a list, so we can easily concatenate
result = np.array([r[i:] + r[:i] for i in range(1, len(r))])

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

This is pretty flexible because the indexing is still meaningful for negative values of i . 这非常灵活,因为索引对于i负值仍然有意义。 So you just have to mess around with range to get the desired start and stop rows, and direction. 因此,您只需要弄乱range即可获得所需的开始行和停止行以及方向。

In particular, to get the exact result you wanted: 特别是,要获得准确的结果,您需要:

np.array([r[i:] + r[:i] for i in range(1, -len(r) + 2, -1)])

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM