零填充numpy数组
Posted
技术标签:
【中文标题】零填充numpy数组【英文标题】:Zero pad numpy array 【发布时间】: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
【问题讨论】:
【参考方案1】:numpy.pad
和 constant
模式可以满足您的需求,我们可以传递一个元组作为第二个参数来告诉每个尺寸要填充多少个零,例如 (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) 应该,因为这里的正确填充长度是1024
和len(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)
),然后分别填写 A
和 zeros
,您可能可以获得稍微更好的性能,但我怀疑加速在大多数情况下,增加代码复杂度是值得的。
要获得要填充的值,我认为您可能只需使用 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:]
【讨论】:
以上是关于零填充numpy数组的主要内容,如果未能解决你的问题,请参考以下文章