【问题标题】:Zero pad numpy array零填充numpy数组
【发布时间】:2016-11-06 14:34:28
【问题描述】:

在数组末尾填充零的更 Pythonic 的方法是什么?

def pad(A, length):
    ...

A = np.array([1,2,3,4,5])
pad(A, 8)    # expected : [1,2,3,4,5,0,0,0]

在我的实际用例中,实际上我想将一个数组填充到最接近 1024 的倍数。例如:1342 => 2048, 3000 => 3072

【问题讨论】:

    标签: python numpy numpy-ndarray zero-pad zero-padding


    【解决方案1】:

    numpy.padconstant 模式可以满足您的需求,我们可以传递一个元组作为第二个参数来告诉每个尺寸要填充多少个零,例如 (2, 3) 将填充 2 左侧为零,右侧 3 个零:

    给定A

    A = np.array([1,2,3,4,5])
    
    np.pad(A, (2, 3), 'constant')
    # array([0, 0, 1, 2, 3, 4, 5, 0, 0, 0])
    

    还可以通过传递元组的元组作为填充宽度来填充二维 numpy 数组,其格式为 ((top, bottom), (left, right))

    A = np.array([[1,2],[3,4]])
    
    np.pad(A, ((1,2),(2,1)), 'constant')
    
    #array([[0, 0, 0, 0, 0],           # 1 zero padded to the top
    #       [0, 0, 1, 2, 0],           # 2 zeros padded to the bottom
    #       [0, 0, 3, 4, 0],           # 2 zeros padded to the left
    #       [0, 0, 0, 0, 0],           # 1 zero padded to the right
    #       [0, 0, 0, 0, 0]])
    

    对于您的情况,您指定左侧为零,右侧 pad 由模除法计算得出:

    B = np.pad(A, (0, 1024 - len(A)%1024), 'constant')
    B
    # array([1, 2, 3, ..., 0, 0, 0])
    len(B)
    # 1024
    

    对于更大的A

    A = np.ones(3000)
    B = np.pad(A, (0, 1024 - len(A)%1024), 'constant')
    B
    # array([ 1.,  1.,  1., ...,  0.,  0.,  0.])
    
    len(B)
    # 3072
    

    【讨论】:

    • 谢谢!如果原始长度为 3000 是否有效? (那么填充长度​​应该是 3072)
    • 应该,因为这里的正确填充长度是1024len(A)的模余数除以1024之间的差。它应该很容易测试。
    • 如果我要填充 3d 卷怎么办?
    • 这真的是我见过的最清晰的例子。谢谢!!
    • mode='constant'为默认值,无需直接指定。文档:numpy.org/doc/stable/reference/generated/numpy.pad.html
    【解决方案2】:

    供将来参考:

    def padarray(A, size):
        t = size - len(A)
        return np.pad(A, pad_width=(0, t), mode='constant')
    
    padarray([1,2,3], 8)     # [1 2 3 0 0 0 0 0]
    

    【讨论】:

      【解决方案3】:

      对于您的用例,您可以使用resize() 方法:

      A = np.array([1,2,3,4,5])
      A.resize(8)
      

      这会调整A 的大小。如果有 A 的引用,numpy 会抛出一个 vale 错误,因为引用的值也会被更新。要允许此添加 refcheck=False 选项。

      文档指出缺失值将是0

      扩大数组:同上,但缺少的条目用零填充

      【讨论】:

      • 感谢@semisecure! 4年后终于有了一个非常简单的解决方案:)
      【解决方案4】:

      np.pad:

      A = np.array([1, 2, 3, 4, 5])
      A = np.pad(A, (0, length), mode='constant')
      

      关于您的用例,需要填充的零数量可以计算为length = len(A) + 1024 - 1024 % len(A)

      【讨论】:

        【解决方案5】:

        这应该可行:

        def pad(A, length):
            arr = np.zeros(length)
            arr[:len(A)] = A
            return arr
        

        如果您初始化一个空数组 (np.empty(length)),然后分别填写 Azeros,您可能可以获得稍微更好的性能,但我怀疑加速在大多数情况下,增加代码复杂度是值得的。

        要获得要填充的值,我认为您可能只需使用 divmod 之类的东西:

        n, remainder = divmod(len(A), 1024)
        n += bool(remainder)
        

        基本上,这只是计算出 1024 将数组长度除以多少次(以及该除法的余数是多少)。如果没有余数,那么您只需要 n * 1024 元素。如果有余数,则需要(n + 1) * 1024

        齐心协力:

        def pad1024(A):
            n, remainder = divmod(len(A), 1024)
            n += bool(remainder)
            arr = np.zeros(n * 1024)
            arr[:len(A)] = A
            return arr        
        

        【讨论】:

        • 谢谢!自动填充以使长度成为 1024 的倍数的任何想法?我正在写一些东西,但它是高度非 Pythonic ;)
        • @Basj -- 当然,检查我的更新。我没有测试它或任何东西,但我认为它应该可以工作......
        • 这就是pad 所做的,但有很多花里胡哨(正面、背面、不同轴、其他填充模式)。
        【解决方案6】:

        你也可以使用numpy.pad:

        >>> A = np.array([1,2,3,4,5])
        >>> npad = 8 - len(A)
        >>> np.pad(A, pad_width=npad, mode='constant', constant_values=0)[npad:]
        array([1, 2, 3, 4, 5, 0, 0, 0])
        

        在一个函数中:

        def pad(A, npads):
            _npads = npads - len(A)
            return np.pad(A, pad_width=_npads, mode='constant', constant_values=0)[_npads:]
        

        【讨论】:

          猜你喜欢
          • 2018-10-05
          • 2017-10-24
          • 2016-06-15
          • 1970-01-01
          • 2018-05-07
          • 2020-06-06
          • 1970-01-01
          • 2015-08-09
          • 1970-01-01
          相关资源
          最近更新 更多