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]]

大きな配列を扱うときにpython forループを避けるためにnumpyでこれを行う方法はありますか?

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配列を形成する1つの方法です。以下で説明するように、この場合は最善の方法ではないことがわかります。


別の可能性は次のとおりです。

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()しないため、最後の要素に追加する余分な要素が必要です。リスト内包表記は、Python ループとしてではなく、Python で C 側に実装されているためzip()、通常のループよりも大幅に高速です。for

別の方法は、次を使用すること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_longestPython 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 に答える