假设我有一个数组(numpy数组)A = [[1, 2, 3], [0, 0, 0], [0, 0, 0]]
,我想将零行操作到[2, 3, 1], [3, 1, 2]
,所以最后一个数组是A = [[1, 2, 3], [2, 3, 1], [3, 1, 2]]
我可以使用for循环执行此操作,如下所示:
a = np.array([[1, 2, 3],[0, 0, 0],[0, 0, 0]])
for i in xrange(1,3):
a[i]=np.concatenate([a[i-1][1:], a[i-1][:1]], axis=1)
转到上一行,连接[1:]和[:1],将结果作为下一行。
我有很多这些循环,我想知道我是否可以摆脱for循环,所以我得到更多的速度(也许?)。有没有办法可以使用列表理解或地图来做到这一点?我的A数组不必是nxn,零行除了第一个,它可以只是A = [1, 2, 3, ..., n]
如果有一种方法我可以创建使用A作为启动器的nx3数组并继续前一行并连接它的[m:]
和[:m]
。 (任意m)
或者是的,也许for循环是进行此类操作的唯一/正确方法。我想知道是不是。
答案 0 :(得分:2)
for循环是最简单的方法,列表理解或映射不会获得太多速度。但您可以使用roll
而不是连接:
a = numpy.array([1, 2, 3])
a = numpy.vstack([numpy.roll(a, -i) for i in xrange(3)])
答案 1 :(得分:1)
我建议使用python zip
内置函数。你可以将数组连接到自身,然后你需要的只是挑选每3个跟随的元素!
>>> A=np.arange(1,4)
>>> B=np.concatenate((A,A))
>>> B
array([1, 2, 3, 1, 2, 3])
>>> np.array(zip(B,B[1:],B[2:])[:-1])
array([[1, 2, 3],
[2, 3, 1],
[3, 1, 2]])
您可以将此配方用于更长的阵列:
>>> A=np.arange(1,6)
>>> B=np.concatenate((A,A))
>>> np.array(zip(B,B[1:],B[2:])[:-1])
array([[1, 2, 3],
[2, 3, 4],
[3, 4, 5],
[4, 5, 1],
[5, 1, 2],
[1, 2, 3],
[2, 3, 4]])
>>>
答案 2 :(得分:0)
这是一个避免Python循环的解决方案。 你可以通过创建一个索引数组来获得所需的输出,你可以用它来索引你的原始数组:
# No extra indentation.
if (this_is_one_thing and
that_is_another_thing):
do_something()
# Add a comment, which will provide some distinction in editors
# supporting syntax highlighting.
if (this_is_one_thing and
that_is_another_thing):
# Since both conditions are true, we can frobnicate.
do_something()
# Add some extra indentation on the conditional continuation line.
if (this_is_one_thing
and that_is_another_thing):
do_something()
这适用于任何In [40]:
a = np.arange(1, 4)
i = np.arange(len(a))
indexer = i - np.atleast_2d(i).T
a[indexer]
Out[40]:
array([[1, 2, 3],
[3, 1, 2],
[2, 3, 1]])
。 a
数组是所需输出的大小,使用广播创建。在这种情况下,它看起来像
indexer
以下是与循环方法的一些时间比较,表明它的速度要快得多:
array([[ 0, 1, 2],
[-1, 0, 1],
[-2, -1, 0]])
这样做的另一个好处是,您可以重复使用In [69]:
%%timeit
a = np.arange(1, 11)
i = np.arange(0, len(a), step_size)
indexer = i - np.atleast_2d(i).T
a[indexer]
10000 loops, best of 3: 14.7 µs per loop
In [70]:
%%timeit
a = numpy.arange(1, 11)
a = numpy.vstack([numpy.roll(a, -i) for i in xrange(len(a))])
10000 loops, best of 3: 143 µs per loop
In [71]:
%%timeit
a = np.arange(1, 101)
i = np.arange(0, len(a), step_size)
indexer = i - np.atleast_2d(i).T
a[indexer]
10000 loops, best of 3: 80 µs per loop
In [72]:
%%timeit
a = numpy.arange(1, 101)
a = numpy.vstack([numpy.roll(a, -i) for i in xrange(len(a))])
1000 loops, best of 3: 1.44 ms per loop
以相同的方式操纵相同长度的其他数组。如果你真的想要你也可以把它写到磁盘上。
对于任意步长indexer
,您可以执行以下操作:
m