繁体   English   中英

将numpy数组排列成ndarray或矩阵

[英]Permutations of a numpy array into an ndarray or matrix

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

我有一个numpy数组foo ,我想转换成ndarry或矩阵,类似于:

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

有关如何有效地执行此操作的任何建议,因为我的源数组foo大小会有所不同,我需要进行数百万次的转换。

你可以在循环中使用np.roll

x = np.array([np.roll(foo, -x) for x in np.arange(foo.shape[0])])

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

为了大规模的表现,我们可以在这里strides 诀窍是将原始数组与以倒数第二个元素结尾的切片数组连接起来,然后获取长度与原始数组长度相同的滑动窗口。

因此,实施将是 -

def strided_method(ar):
    a = np.concatenate(( ar, ar[:-1] ))
    L = len(ar)
    n = a.strides[0]
    return np.lib.stride_tricks.as_strided(a, (L,L), (n,n), writeable=False)

输出将是只读的,并且连接数组的视图因此几乎与数组大小无关地具有恒定时间。 这意味着一个非常有效的解决方案。 如果您需要具有自己的存储空间的可写输出,请在那里复制,如稍后的时间所示。

样品运行 -

In [51]: foo = np.array([1,2,3,4])

In [52]: strided_method(foo)
Out[52]: 
array([[1, 2, 3, 4],
       [2, 3, 4, 1],
       [3, 4, 1, 2],
       [4, 1, 2, 3]])

运行时测试 -

In [53]: foo = np.random.randint(0,9,(1000))

# @cᴏʟᴅsᴘᴇᴇᴅ's loopy soln
In [54]: %timeit np.array([np.roll(foo, -x) for x in np.arange(foo.shape[0])])
100 loops, best of 3: 12.7 ms per loop

In [55]: %timeit strided_method(foo)
100000 loops, best of 3: 7.46 µs per loop

In [56]: %timeit strided_method(foo).copy()
1000 loops, best of 3: 454 µs per loop

这些矩阵称为Hankel矩阵。 大多数平台已经提供了创建它们的特定例程。 您也可以通过删除不必要的部分来实现自己,以提高速度。 这是一个非常简洁的代码

from scipy.linalg import hankel

A = hankel([1,2,3,4], [4,1,2,3])
A
array([[1, 2, 3, 4],
       [2, 3, 4, 1],
       [3, 4, 1, 2],
       [4, 1, 2, 3]])

它似乎比Divakar的解决方案慢了约2倍,而且速度惊人的快。

暂无
暂无

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

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