最後に、L-1
の行を最後に追加して、配列の先頭に追加する方法があります。それでは、非常に効率的なNumPy strides
を使用する単純なケースになります。このトリックのコストについて疑問を抱く人にとっては、タイミングテストを通して後で説明するように、それは何も得意ではありません。
両方の前方と後方のコードに跨ぐはこのようになりますサポートする最終的な目標件までをリードするトリック -
後方ストライド:
def strided_axis0_backward(inArr, L = 2):
# INPUTS :
# a : Input array
# L : Length along rows to be cut to create per subarray
# Append the last row to the start. It just helps in keeping a view output.
a = np.vstack((inArr[-L+1:], inArr))
# Store shape and strides info
m,n = a.shape
s0,s1 = a.strides
# Length of 3D output array along its axis=0
nd0 = m - L + 1
strided = np.lib.stride_tricks.as_strided
return strided(a[L-1:], shape=(nd0,L,n), strides=(s0,-s0,s1))
フォワードストライド:
def strided_axis0_forward(inArr, L = 2):
# INPUTS :
# a : Input array
# L : Length along rows to be cut to create per subarray
# Append the last row to the start. It just helps in keeping a view output.
a = np.vstack((inArr , inArr[:L-1]))
# Store shape and strides info
m,n = a.shape
s0,s1 = a.strides
# Length of 3D output array along its axis=0
nd0 = m - L + 1
strided = np.lib.stride_tricks.as_strided
return strided(a[:L-1], shape=(nd0,L,n), strides=(s0,s0,s1))
サンプルラン -
In [42]: inArr
Out[42]:
array([[1, 2],
[3, 4],
[5, 6]])
In [43]: strided_axis0_backward(inArr, 2)
Out[43]:
array([[[1, 2],
[5, 6]],
[[3, 4],
[1, 2]],
[[5, 6],
[3, 4]]])
In [44]: strided_axis0_forward(inArr, 2)
Out[44]:
array([[[1, 2],
[3, 4]],
[[3, 4],
[5, 6]],
[[5, 6],
[1, 2]]])
ランタイムテスト - strided_axis0
の
In [53]: inArr = np.random.randint(0,9,(1000,10))
In [54]: %timeit make_timesteps(inArr, 2)
...: %timeit strided_axis0_forward(inArr, 2)
...: %timeit strided_axis0_backward(inArr, 2)
...:
10 loops, best of 3: 33.9 ms per loop
100000 loops, best of 3: 12.1 µs per loop
100000 loops, best of 3: 12.2 µs per loop
In [55]: %timeit make_timesteps(inArr, 10)
...: %timeit strided_axis0_forward(inArr, 10)
...: %timeit strided_axis0_backward(inArr, 10)
...:
1 loops, best of 3: 152 ms per loop
100000 loops, best of 3: 12 µs per loop
100000 loops, best of 3: 12.1 µs per loop
In [56]: 152000/12.1 # Speedup figure
Out[56]: 12561.98347107438
タイミングが、我々は、出力にサブアレイの長さを増加させたとしても同じまま。それはちょうど私達にstrides
と巨大な恩恵を示してくれるだけでなく、元の偽のバージョンよりも狂気のスピードアップを示しています。タイミングはかなり効率的な一つであることがスタッキングの考えを支持
In [417]: inArr = np.random.randint(0,9,(1000,10))
In [418]: L = 10
In [419]: %timeit np.vstack((inArr[-L+1:], inArr))
100000 loops, best of 3: 5.41 µs per loop
- 開始時に約束したよう
、ここでタイミングがnp.vstack
とコストを積み重ねの上にあります。
本当に助けてくれました。以前はas_stridedと思っていましたが、あなたの例とリンクまで理解できませんでした。私は最終的なコードを表示するために質問を編集しました。同じ順序を得るために、私は最初の行を最後に追加し、次に軸1にnp.flipを追加しました。 – nickyzee
@nickyzeeなぜ私は「フリップ」が必要なのか分かりません。あなたの 'make_timesteps'は正しいですか?' make_timesteps'と同じ結果を出すようにコーディングしたからです。あなたのフリップの提案では、私のコードは 'make_timesteps'とは異なる結果をもたらします。これを明確にする?面白い - 私は元のものと同じ出力を作るためにフリップが必要です。 – Divakar
出力の目視検査もこれを確認します。私が元々返す 'array [[[1、2]、 [3,4]]、 [[3,4]、 [5、6]] 、 [5,6]、 [7、8]、 [7、8]、 [1、2]]]) ' – nickyzee