python如何用零填充numpy数组 [英] python how to pad numpy array with zeros

查看:33
本文介绍了python如何用零填充numpy数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道如何使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆