数年前のこの質問のフォローアップとして、numpyに正規の「シフト」機能はありますか?ドキュメントから何も表示されません。
これが私が探しているものの簡単なバージョンです:
def shift(xs, n):
if n >= 0:
return np.r_[np.full(n, np.nan), xs[:-n]]
else:
return np.r_[xs[-n:], np.full(-n, np.nan)]
これを使用すると、次のようになります。
In [76]: xs
Out[76]: array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
In [77]: shift(xs, 3)
Out[77]: array([ nan, nan, nan, 0., 1., 2., 3., 4., 5., 6.])
In [78]: shift(xs, -3)
Out[78]: array([ 3., 4., 5., 6., 7., 8., 9., nan, nan, nan])
この質問は、昨日高速のrolling_productを作成しようとしたときに発生しました。累積積を「シフト」する方法が必要でしたnp.roll()
。考えられるのは、のロジックを複製することだけでした。
したがってnp.concatenate()
、よりもはるかに高速ですnp.r_[]
。このバージョンの関数のパフォーマンスは大幅に向上しています。
def shift(xs, n):
if n >= 0:
return np.concatenate((np.full(n, np.nan), xs[:-n]))
else:
return np.concatenate((xs[-n:], np.full(-n, np.nan)))
さらに高速なバージョンでは、配列を事前に割り当てるだけです。
def shift(xs, n):
e = np.empty_like(xs)
if n >= 0:
e[:n] = np.nan
e[n:] = xs[:-n]
else:
e[n:] = np.nan
e[:n] = xs[-n:]
return e
np.r_[np.full(n, np.nan), xs[:-n]]
置き換えることができるかどうか疑問に思いますnp.r_[[np.nan]*n, xs[:-n]]
np.full