3

Python でスライスを反転する一般的な方法を探しています。この包括的な投稿を読みました。これには、スライスの仕組みについていくつかの素晴らしい説明があります: Understanding Python's slice notation

それでも、まったく同じ要素を逆の順序でアドレス指定する逆スライスを計算する方法に関する一般化されたルールを理解することはできません。これを行う組み込みメソッドが見つからないことに、私は実際に驚きました。

私が探しているのは、reversed_slice任意startの 、stopおよびstep負の値を含む値で次のように機能するメソッドです。

>>> import numpy as np
>>> a = np.arange(30)
>>> s = np.s_[10:20:2]
>>> a[s]
array([10, 12, 14, 16, 18])
>>> a[reversed_slice(s,len(a))]
array([18, 16, 14, 12, 10])

私が試したがうまくいかないのはこれです:

def reversed_slice(slice_, len_):
    """
    Reverses a slice (selection in array of length len_), 
    addressing the same elements in reverse order.
    """
    assert isinstance(slice_, slice)
    instart, instop, instep = slice_.indices(len_)
    if instep > 0:
        start, stop, step = instop - 1, instart - 1, -instep
    else:
        start, stop, step = instop + 1, instart + 1, -instep
    return slice(start, stop, step)

1これは、最後のアドレス指定された要素が と一致する場合に、 のステップに対して正常に機能しstop-1ます。それ以外の場合は、次のことはしません。

>>> import numpy as np
>>> a = np.arange(30)
>>> s = np.s_[10:20:2]
>>> a[s]
array([10, 12, 14, 16, 18])
>>> a[reversed_slice(s,len(a))]
array([19, 17, 15, 13, 11])

のような関係が欠けているよう(stop - start) % stepです。一般的なメソッドの書き方に関するヘルプは大歓迎です。

ノート:

  • を呼び出すなど、同じ要素を逆にしたシーケンスを取得する他の可能性があることは知っていますreversed(a[s])。スライス自体を逆にする必要があるため、これはここではオプションではありません。その理由は、スライスにh5py負の値を許可しないデータセットに取り組んでいるためです。step

  • 簡単ですがあまり洗練されていない方法は、座標リストを使用することa[list(reversed(range(*s.indices(len(a)))))]です。h5pyリスト内のインデックスは昇順で指定する必要があるため、これもオプションではありません。

4

5 に答える 5

3

には負の値を指定できますstep

>>> s = np.s_[20-2:10-2:-2]
>>> a[s]
array([18, 16, 14, 12, 10])

reversed_sliceしたがって、次のように関数を構築できます

>>> def reversed_slice(s):
...     """
...     Reverses a slice 
...     """
...     m = (s.stop-s.start) % s.step or s.step
...     return slice(s.stop-m, s.start-m, -s.step)
... 
>>> a = np.arange(30)
>>> s = np.s_[10:20:2]
>>> a[reversed_slice(s)]
array([18, 16, 14, 12, 10])
>>> 
>>> a[reversed_slice(reversed_slice(s))]
array([10, 12, 14, 16, 18])
>>> 
于 2018-07-06T11:51:02.170 に答える