python如何用零填充numpy数组 [英] python how to pad numpy array with zeros
问题描述
我想知道如何使用 python 2.6.6 和 numpy 版本 1.5.0 用零填充二维 numpy 数组.但这些都是我的局限.因此我不能使用 np.pad
.例如,我想用零填充 a
,使其形状与 b
匹配.我之所以要这样做,是因为我可以这样做:
b-a
这样
<预><代码>>>>一种数组([[ 1., 1., 1., 1., 1.],[ 1., 1., 1., 1., 1.],[ 1., 1., 1., 1., 1.]])>>>乙数组([[ 3., 3., 3., 3., 3., 3.],[ 3., 3., 3., 3., 3., 3.],[ 3., 3., 3., 3., 3., 3.],[ 3., 3., 3., 3., 3., 3.]])>>>C数组([[1, 1, 1, 1, 1, 0],[1, 1, 1, 1, 1, 0],[1, 1, 1, 1, 1, 0],[0, 0, 0, 0, 0, 0]])我能想到的唯一方法是追加,但这看起来很丑陋.是否有可能使用 b.shape
的更清洁的解决方案?
编辑,感谢 MSeiferts 的回答.我不得不清理一下,这就是我得到的:
def pad(array, reference_shape, offsets):"数组:要填充的数组reference_shape:要创建的 ndarray 大小的元组offsets:偏移量列表(元素数量必须等于数组的维数)如果偏移量太大并且 reference_shape 无法处理偏移量,则会抛出 ValueError"# 创建一个具有参考形状的零数组结果 = np.zeros(reference_shape)# 在每个维度创建一个从 offset 到 offset + shape 的切片列表insertHere = [slice(offsets[dim], offsets[dim] + array.shape[dim]) for dim in range(array.ndim)]# 在结果中指定偏移量处插入数组结果[插入此处] = 数组返回结果
非常简单,您使用参考形状创建一个包含零的数组:
result = np.zeros(b.shape)# 实际上你也可以使用 result = np.zeros_like(b)# 但这也不仅复制了形状,而且还复制了 dtype
然后在需要的地方插入数组:
result[:a.shape[0],:a.shape[1]] = a
瞧,你已经填充了它:
打印(结果)数组([[ 1., 1., 1., 1., 1., 0.],[ 1., 1., 1., 1., 1., 0.],[ 1., 1., 1., 1., 1., 0.],[ 0., 0., 0., 0., 0., 0.]])
<小时>
如果您定义左上角元素应插入的位置,您也可以使其更通用
result = np.zeros_like(b)x_offset = 1 # 0 就是你想要的y_offset = 1 # 0 在你的情况下结果[x_offset:a.shape[0]+x_offset,y_offset:a.shape[1]+y_offset] = a结果数组([[ 0., 0., 0., 0., 0., 0.],[ 0., 1., 1., 1., 1., 1.],[ 0., 1., 1., 1., 1., 1.],[ 0., 1., 1., 1., 1., 1.]])
但是要注意偏移量不要超过允许值.例如,对于 x_offset = 2
这将失败.
如果你有任意数量的维度,你可以定义一个切片列表来插入原始数组.我发现稍微玩一下很有趣,并创建了一个填充函数,只要数组和引用具有相同的维数并且偏移量不太大,就可以填充(使用偏移量)任意形状的数组.>
def pad(array, reference, offsets):"""数组:要填充的数组参考:具有所需形状的参考数组offsets:偏移量列表(元素数量必须等于数组的维数)"""# 创建一个具有参考形状的零数组结果 = np.zeros(reference.shape)# 在每个维度创建一个从 offset 到 offset + shape 的切片列表insertHere = [slice(offset[dim], offset[dim] + array.shape[dim]) for dim in range(a.ndim)]# 在结果中指定偏移量处插入数组结果[插入此处] = a返回结果
还有一些测试用例:
将 numpy 导入为 np# 1 维度a = np.ones(2)b = np.ones(5)偏移量 = [3]垫(a,b,偏移)# 3 维度a = np.ones((3,3,3))b = np.ones((5,4,3))偏移量 = [1,0,0]垫(a,b,偏移)
I want to know how I can pad a 2D numpy array with zeros using python 2.6.6 with numpy version 1.5.0. But these are my limitations. Therefore I cannot use np.pad
. For example, I want to pad a
with zeros such that its shape matches b
. The reason why I want to do this is so I can do:
b-a
such that
>>> a
array([[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.],
[ 1., 1., 1., 1., 1.]])
>>> b
array([[ 3., 3., 3., 3., 3., 3.],
[ 3., 3., 3., 3., 3., 3.],
[ 3., 3., 3., 3., 3., 3.],
[ 3., 3., 3., 3., 3., 3.]])
>>> c
array([[1, 1, 1, 1, 1, 0],
[1, 1, 1, 1, 1, 0],
[1, 1, 1, 1, 1, 0],
[0, 0, 0, 0, 0, 0]])
The only way I can think of doing this is appending, however this seems pretty ugly. is there a cleaner solution possibly using b.shape
?
Edit, Thank you to MSeiferts answer. I had to clean it up a bit, and this is what I got:
def pad(array, reference_shape, offsets):
"""
array: Array to be padded
reference_shape: tuple of size of ndarray to create
offsets: list of offsets (number of elements must be equal to the dimension of the array)
will throw a ValueError if offsets is too big and the reference_shape cannot handle the offsets
"""
# Create an array of zeros with the reference shape
result = np.zeros(reference_shape)
# Create a list of slices from offset to offset + shape in each dimension
insertHere = [slice(offsets[dim], offsets[dim] + array.shape[dim]) for dim in range(array.ndim)]
# Insert the array in the result at the specified offsets
result[insertHere] = array
return result
Very simple, you create an array containing zeros using the reference shape:
result = np.zeros(b.shape)
# actually you can also use result = np.zeros_like(b)
# but that also copies the dtype not only the shape
and then insert the array where you need it:
result[:a.shape[0],:a.shape[1]] = a
and voila you have padded it:
print(result)
array([[ 1., 1., 1., 1., 1., 0.],
[ 1., 1., 1., 1., 1., 0.],
[ 1., 1., 1., 1., 1., 0.],
[ 0., 0., 0., 0., 0., 0.]])
You can also make it a bit more general if you define where your upper left element should be inserted
result = np.zeros_like(b)
x_offset = 1 # 0 would be what you wanted
y_offset = 1 # 0 in your case
result[x_offset:a.shape[0]+x_offset,y_offset:a.shape[1]+y_offset] = a
result
array([[ 0., 0., 0., 0., 0., 0.],
[ 0., 1., 1., 1., 1., 1.],
[ 0., 1., 1., 1., 1., 1.],
[ 0., 1., 1., 1., 1., 1.]])
but then be careful that you don't have offsets bigger than allowed. For x_offset = 2
for example this will fail.
If you have an arbitary number of dimensions you can define a list of slices to insert the original array. I've found it interesting to play around a bit and created a padding function that can pad (with offset) an arbitary shaped array as long as the array and reference have the same number of dimensions and the offsets are not too big.
def pad(array, reference, offsets):
"""
array: Array to be padded
reference: Reference array with the desired shape
offsets: list of offsets (number of elements must be equal to the dimension of the array)
"""
# Create an array of zeros with the reference shape
result = np.zeros(reference.shape)
# Create a list of slices from offset to offset + shape in each dimension
insertHere = [slice(offset[dim], offset[dim] + array.shape[dim]) for dim in range(a.ndim)]
# Insert the array in the result at the specified offsets
result[insertHere] = a
return result
And some test cases:
import numpy as np
# 1 Dimension
a = np.ones(2)
b = np.ones(5)
offset = [3]
pad(a, b, offset)
# 3 Dimensions
a = np.ones((3,3,3))
b = np.ones((5,4,3))
offset = [1,0,0]
pad(a, b, offset)
这篇关于python如何用零填充numpy数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!