列表理解或map()或for循环访问前一行来操作数组

时间:2015-07-05 09:00:51

标签: python arrays loops numpy list-comprehension

假设我有一个数组(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循环是进行此类操作的唯一/正确方法。我想知道是不是。

3 个答案:

答案 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