python - 在 Python 中反转任意切片

标签 python slice numpy-slicing

我正在寻找一种关于如何在 Python 中反转切片的通用方法。 我阅读了这篇综合文章,其中对切片的工作原理有几个很好的解释: Understanding Python's slice notation

但是我无法找出关于如何计算反向切片的通用规则,该反向切片以相反的顺序处理完全相同的元素。我真的很惊讶没有找到这样做的内置方法。

我正在寻找的是一种方法 reversed_slice 可以像这样使用任意 startstopstep 值包括负值:

>>> 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 要求列表中的索引必须按递增顺序给出。

最佳答案

您可以为 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])
>>> 

关于python - 在 Python 中反转任意切片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51209749/

相关文章:

go - struct指针的slice成员未更新

python - 根据坐标列表从 ndarray 构造一个 ndarray

python - padding_idx 在 nn.embeddings() 中做什么

go - 将整数 slice append 到整数 slice 的 slice 会修改被 append 的 slice

python - django-filter:使用 ChoiceFilter 并根据请求进行选择

go - 使用带有标量或 slice 的函数

matplotlib - 对图像的 channel 进行切片并将 channel 存储到 numpy 数组中(与图像大小相同)。绘制 numpy 数组而不给出原始图像

python - 为什么对 numpy 数组的就地修改性能与被修改的维度顺序有关?

python - 在 lambda 中使用 print

python - 在执行 Python 脚本时替换 Python 扩展模块时出现问题