7

我有一个数组:

t = [4, 5, 0, 7, 1, 6, 8, 3, 2, 9]

这只是范围 [0, 9] 的随机洗牌。我需要计算这个:

t2 = [9, 5, 7, 8, 7, 14, 11, 5, 11, 13]

这只是:

t2 = [t[0]+t[1], t[1]+t[2], t[2]+t[3], t[3]+t[4], ..., t[9]+t[0]]

有没有办法在处理大型数组时使用 numpy 来避免 python for 循环?

4

3 回答 3

20

您可以利用 NumPy 数组对元素求和的能力:

In [5]: import numpy as np

In [6]: t = np.array([4, 5, 0, 7, 1, 6, 8, 3, 2, 9])

In [7]: t + np.r_[t[1:],t[0]]
Out[7]: array([ 9,  5,  7,  8,  7, 14, 11,  5, 11, 13])

np.r_是将序列连接在一起以形成新的 numpy 数组的一种方法。正如我们将在下面看到的,在这种情况下,这并不是最好的方法。


另一种可能是:

In [10]: t + np.roll(t,-1)
Out[10]: array([ 9,  5,  7,  8,  7, 14, 11,  5, 11, 13])

看起来使用np.roll速度明显更快:

In [11]: timeit t + np.roll(t,-1)
100000 loops, best of 3: 17.2 us per loop

In [12]: timeit t + np.r_[t[1:],t[0]]
10000 loops, best of 3: 35.5 us per loop
于 2012-04-28T19:19:59.257 回答
1

zip()您可以使用、列表切片和列表推导非常愉快地做到这一点:

t2 = [a+b for (a, b) in zip(t, t[1:])]
t2.append(t[0]+t[-1])

我们需要append()在最后一个元素中添加额外的元素,因为zip()它只在最短的迭代器结束之前有效。列表推导比普通for循环快得多,因为它是在 Python 中实现的 C 端,而不是作为 Python 循环。

另一种方法是使用itertools.zip_longest

from itertools import zip_longest
t2 = [a+b for (a, b) in zip_longest(t, t[1:], fillvalue=t[0])]

填写额外的值。请注意,此函数itertools.izip_longest在 Python 2.x 中。

于 2012-04-28T19:12:42.187 回答
1

关于什么

import numpy as np
t = np.array([4, 5, 0, 7, 1, 6, 8, 3, 2, 9])

new_t = t + np.hstack((t[1:], [t[0]]))

结果:

>>> new_t
array([ 9,  5,  7,  8,  7, 14, 11,  5, 11, 13])
于 2012-04-28T22:48:10.987 回答