【问题标题】:Skipping rows in numpy ndarrays slicing在numpy ndarrays切片中跳过行
【发布时间】:2018-06-22 14:36:07
【问题描述】:

假设我有一个 numpy 数组 imgimg.shape == (468,832,3)img[::2, ::2] 是做什么的?将形状缩小为(234,416,3) 能否解释一下逻辑?

【问题讨论】:

    标签: python numpy multidimensional-array


    【解决方案1】:

    它从一个数组中分割每个交替的行,然后是每个交替的列,返回一个大小为(n // 2, n // 2, ...)的数组。

    这是一个使用 2D 数组进行切片的示例 -

    >>> a = np.arange(16).reshape(4, 4)
    >>> a
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11],
           [12, 13, 14, 15]])
    

    >>> a[::2, ::2]
    array([[ 0,  2],
           [ 8, 10]])
    

    还有一个 3D 数组的例子 -

    >>> a = np.arange(27).reshape(3, 3, 3)
    >>> a
    array([[[ 0,  1,  2],
            [ 3,  4,  5],
            [ 6,  7,  8]],
    
           [[ 9, 10, 11],
            [12, 13, 14],
            [15, 16, 17]],
    
           [[18, 19, 20],
            [21, 22, 23],
            [24, 25, 26]]])
    

    >>> a[::2, ::2] # same as a[::2, ::2, :]
    array([[[ 0,  1,  2],
            [ 6,  7,  8]],
    
           [[18, 19, 20],
            [24, 25, 26]]])
    

    【讨论】:

    • 你能解释一下[: : 2, : : 2]如何分割3d数组语言(noob语言)的交替行和列吗?
    • @VaishnavMK 再举一个例子应该会更清楚。这不是你解释的事情,而是理解。您正在指定切片的“轴”。
    【解决方案2】:

    让我们一起阅读文档(Source). (请先阅读粗体部分)

    基本切片语法是i:j:k,其中i起始索引j停止索引k(k \neq 0)。这会选择索引值为 i, i + k, ..., i + (m - 1) k 的 m 个元素(在相应维度中),其中 m = q + (r\neq0) 和 q 和 r 是 j - i 除以 k 得到的商和余数: j - i = qk + r,使得 i + (m - 1) k

    ...

    假设 n 是被切片的维度中的元素数。 然后,如果没有给出 i,k > 0 时默认为 0,k 如果 j 没有给出,它默认为 n 代表 k > 0 和 -n-1 代表 k

    现在看看你的部分。

    [::2, ::2] 将被转换为[0:468:2, 0:832:2],因为您没有在文档中指定前两个或ij。 (您只在此处指定k。回想上面的i:j:k 符号。)您以步长2 选择这些轴上的元素,这意味着您沿着指定的轴选择所有其他元素。

    因为您没有指定第 3 个维度,所以将全部选中。

    【讨论】:

    • 谢谢!最后一行解决了我的问题。我对 3d 数组没有第三个索引感到困惑。
    • @VaishnavMK 没问题:P
    • 我明白你为什么会有这种感觉。对不起,如果它真的很傻。但是我昨天基本上开始使用 numpy 和 3d 数组切片,并且完全迷失在高级切片与基本切片的对比中,所以我还没有真正开始玩,只是通过在这里提问来探索基本概念。
    【解决方案3】:

    嗯,我们将 RGB 图像作为 3D 形状数组:

    img.shape=(468,832,3)
    

    现在,img[::2, ::2] 做了什么?

    我们只是对图像进行下采样(即,我们通过从原始图像中每隔一个像素来将图像大小缩小一半,我们通过以下方式做到这一点使用2的步长,这意味着跳过一个像素)。从下面的示例中应该可以清楚地看到这一点。

    让我们拍一张简单的灰度图像以便于理解。

    In [13]: arr
    Out[13]: 
    array([[10, 11, 12, 13, 14, 15],
           [20, 21, 22, 23, 24, 25],
           [30, 31, 32, 33, 34, 35],
           [40, 41, 42, 43, 44, 45],
           [50, 51, 52, 53, 54, 55],
           [60, 61, 62, 63, 64, 65]])
    
    In [14]: arr.shape
    Out[14]: (6, 6)
    
    In [15]: arr[::2, ::2]
    Out[15]: 
    array([[10, 12, 14],
           [30, 32, 34],
           [50, 52, 54]])
    
    In [16]: arr[::2, ::2].shape
    Out[16]: (3, 3)
    

    注意哪些像素在切片版本中。另外,观察数组shape在切片后如何变化(即减半)。

    现在,图像中的所有三个通道都会进行这种下采样,因为在第三轴上没有发生切片。因此,您将仅在示例中的前两个轴上缩小形状。

    (468, 832, 3)
      .    .   |
      .    .   |
    (234, 416, 3)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-27
      • 2011-12-07
      • 2019-08-26
      • 1970-01-01
      • 1970-01-01
      • 2019-06-26
      • 2016-02-10
      • 2012-11-14
      相关资源
      最近更新 更多