numpy pad一个序列而不是常量值

时间:2018-02-22 14:10:20

标签: python numpy

我试图在每一行填充一个序列为[0, 1]的numpy数组。例如,如果我有一个数组:

x = np.random.rand(2, 4)

array([[0.51352468, 0.4274193 , 0.11244252, 0.56787658],
       [0.37855923, 0.80976327, 0.0290558 , 0.87585656]])

填充操作后,它变为:

array([[0.51352468, 0.4274193 , 0.11244252, 0.56787658],
       [0.37855923, 0.80976327, 0.0290558 , 0.87585656],
       [0.        , 0.        , 0.        , 0.        ],
       [1.        , 1.        , 1.        , 1.        ]])

目前,我这样做的方式是:

padded = np.asarray(x)
padded = np.pad(padded, [(0, 4 - len(padded.shape[0])), (0, 0)], 'constant')
padded[:, -1] = 1.0

这似乎有点麻烦,因为我用零填充然后将最后一行设置为1.我想知道是否有办法只用一个numpy.pad调用来执行此操作?

修改

从上面的代码中可以看出,该函数将输入转换为4维对象(数组的输入维度为2或3,即len(x)== 2或3)。因此,如果输入是2维,它将添加两行零,然后将最后一行设置为1.如果输入是3维,它将添加一行零,然后覆盖到一行。

3 个答案:

答案 0 :(得分:2)

如果只是简单地分配一个零的二维数组,或许它会更简单(读取), 将1分配给最后一行,并将x复制到填充数组中:

import numpy as np
def pad(x):
    nrows, ncols = x.shape
    padded = np.zeros((4, ncols))
    padded[-1, :] = 1
    padded[:nrows, :] = x
    return padded

nrows, ncols = np.random.randint(2, 4), 4
x = np.random.rand(nrows, ncols)
padded = pad(x)

产生一个填充数组,例如

array([[ 0.38746512,  0.23166218,  0.97459752,  0.37565333],
       [ 0.05774882,  0.44061104,  0.06661526,  0.26714634],
       [ 0.00805322,  0.30201519,  0.71373347,  0.08288743],
       [ 1.        ,  1.        ,  1.        ,  1.        ]])

array([[ 0.68343436,  0.6108459 ,  0.84325679,  0.10912022],
       [ 0.547983  ,  0.7543816 ,  0.02411474,  0.02711809],
       [ 0.        ,  0.        ,  0.        ,  0.        ],
       [ 1.        ,  1.        ,  1.        ,  1.        ]])

取决于行x的行数(假设为< = 4)。

答案 1 :(得分:1)

这似乎不适合使用np.pad。您也可以使用appendrepeat

In [48]: a, b = x.shape
In [49]: np.append(x, np.repeat([[0],[1]], b, axis=1), axis=0)
Out[49]: 
array([[ 0.2129145 ,  0.68606654,  0.53354256,  0.19112299],
       [ 0.11836389,  0.71193408,  0.49222709,  0.60790186],
       [ 0.        ,  0.        ,  0.        ,  0.        ],
       [ 1.        ,  1.        ,  1.        ,  1.        ]])

如果要将变量用于您要插入的零行数,可以使用np.zeros()和inplace unpacking技巧,如下所示:

In [84]: np.append(x, np.repeat([*np.zeros(z_num)[:, None],[1]], b, axis=1), axis=0) # b is x.shape[1]

其中z_num表示零行数。然后,您可以根据输入数组的大小更改此变量。

示例:

In [84]: np.append(x, np.repeat([*np.zeros(0)[:, None],[1]], b, axis=1), axis=0)
Out[84]: 
array([[ 0.38922514,  0.75096968,  0.71939798,  0.84233763],
       [ 0.8055875 ,  0.29738511,  0.57563254,  0.45073955],
       [ 0.94241764,  0.27107424,  0.24536665,  0.60723426],
       [ 1.        ,  1.        ,  1.        ,  1.        ]])

In [85]: 

In [85]: np.append(x, np.repeat([*np.zeros(3)[:, None],[1]], b, axis=1), axis=0)
Out[85]: 
array([[ 0.38922514,  0.75096968,  0.71939798,  0.84233763],
       [ 0.8055875 ,  0.29738511,  0.57563254,  0.45073955],
       [ 0.94241764,  0.27107424,  0.24536665,  0.60723426],
       [ 0.        ,  0.        ,  0.        ,  0.        ],
       [ 0.        ,  0.        ,  0.        ,  0.        ],
       [ 0.        ,  0.        ,  0.        ,  0.        ],
       [ 1.        ,  1.        ,  1.        ,  1.        ]])

答案 2 :(得分:1)

只是为了好玩,这是一种使用np.pad填充0和1的方法:

写一点填充功能。

def pad_with(vector, pad_width, iaxis, kwargs):
    # print(vector, pad_width,iaxis)
    if iaxis==0: vector[-1] = 1
    return vector

这足以改变文档中的示例,以便在此处工作。 print行有助于了解pad传递的内容。

因此,操作由第二个焊盘宽度编号确定:

In [31]: np.pad(x, [[0,1],[0,0]],pad_with)
Out[31]: 
array([[0, 1, 2, 3],
       [4, 5, 6, 7],
       [1, 1, 1, 1]])
In [32]: np.pad(x, [[0,2],[0,0]],pad_with)
Out[32]: 
array([[0, 1, 2, 3],
       [4, 5, 6, 7],
       [0, 0, 0, 0],
       [1, 1, 1, 1]])
In [33]: np.pad(x, [[0,4],[0,0]],pad_with)
Out[33]: 
array([[0, 1, 2, 3],
       [4, 5, 6, 7],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [1, 1, 1, 1]])

打印时间:

In [27]: np.pad(x, [[0,1],[0,0]],pad_with)
[0 4 0] (0, 1) 0
[1 5 0] (0, 1) 0
[2 6 0] (0, 1) 0
[3 7 0] (0, 1) 0
[0 1 2 3] (0, 0) 1
[4 5 6 7] (0, 0) 1
[1 1 1 1] (0, 0) 1
Out[27]: 
array([[0, 1, 2, 3],
       [4, 5, 6, 7],
       [1, 1, 1, 1]])

因此pad遍历每一行和每一行,并传递给此函数0填充vector。然后,该功能可以修改它,甚至可以更改内部值。这里有很多一般性,但是对于这个简单的问题而言已经过时了。