我有一个数组:
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循环?
答案 0 :(得分:18)
你可以利用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
答案 1 :(得分:1)
您可以使用zip()
,列表切片和a list comprehension非常愉快地执行此操作:
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])]
要填充额外的值。请注意Python 2.x中的此函数为itertools.izip_longest
。
答案 2 :(得分: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])