向每个子数组添加1的列向量

时间:2017-10-31 13:39:58

标签: python arrays numpy

假设我有一个零的3d数组,

import numpy as np
a = np.zeros((8,3,4))

并希望在每个子数组中附加一个列向量:

from statsmodels.add_tools import add_constant
print(np.array([add_constant(i, prepend=False) for i in a])[:3])
[[[ 0.  0.  0.  0.  1.]
  [ 0.  0.  0.  0.  1.]
  [ 0.  0.  0.  0.  1.]]

 [[ 0.  0.  0.  0.  1.]
  [ 0.  0.  0.  0.  1.]
  [ 0.  0.  0.  0.  1.]]

 [[ 0.  0.  0.  0.  1.]
  [ 0.  0.  0.  0.  1.]
  [ 0.  0.  0.  0.  1.]]]

有比上述更快的方法吗?没有np.apply_along_axis的运气,尽管我不怀疑反正会更快。我认为像np.insert(a, slice(...?), 1.)这样的东西可能是更好的选择。

4 个答案:

答案 0 :(得分:2)

Divakar建议的替代方案是np.dstack

np.dstack((a, np.ones(a.shape[:-1] + (1, ))))

array([[[ 0.,  0.,  0.,  0.,  1.],
        [ 0.,  0.,  0.,  0.,  1.],
        [ 0.,  0.,  0.,  0.,  1.]],

       [[ 0.,  0.,  0.,  0.,  1.],
        [ 0.,  0.,  0.,  0.,  1.],
        [ 0.,  0.,  0.,  0.,  1.]],
a = np.zeros((800,300,400))

%timeit np.dstack((a, np.ones(a.shape[:-1] + (1, ))))
1 loop, best of 3: 433 ms per loop

答案 1 :(得分:2)

方法#1

这是一个np.concatenate -

def append_ones_concat(a):
    ones_ar = np.ones((a.shape[:-1]+(1,)),dtype=a.dtype)
    return np.concatenate((a, ones_ar), axis=-1)

示例运行 -

In [189]: a = np.zeros((2,3,4))

In [190]: append_ones(a)
Out[190]: 
array([[[ 0.,  0.,  0.,  0.,  1.],
        [ 0.,  0.,  0.,  0.,  1.],
        [ 0.,  0.,  0.,  0.,  1.]],

       [[ 0.,  0.,  0.,  0.,  1.],
        [ 0.,  0.,  0.,  0.,  1.],
        [ 0.,  0.,  0.,  0.,  1.]]])

方法#2

使用array-initialization -

def append_ones_init(a):
    shp = np.array(a.shape)
    shp[-1] += 1
    out = np.ones(shp,dtype=a.dtype)
    out[...,:-1] = a
    return out

方法#3

numba基于concatenate数据集的基于3D的边际改进 -

from numba import njit

def append_ones_numba(a):
    shp = np.array(a.shape)
    shp[-1] += 1
    out = np.empty(shp,dtype=a.dtype)
    append_ones_numba_func(a, out)
    return out

@njit
def append_ones_numba_func(a, out):
    m,n,r = out.shape
    for i in range(m):
        for j in range(n):
            for k in range(r-1):
                out[i,j,k] = a[i,j,k]
            out[i,j,r-1] = 1

计时 -

In [273]: a = np.zeros((800,300,400))

In [274]: %timeit append_ones_init(a)
     ...: %timeit append_ones_concat(a)
     ...: %timeit append_ones_numba(a)
10 loops, best of 3: 136 ms per loop
10 loops, best of 3: 113 ms per loop
1 loop, best of 3: 105 ms per loop

答案 2 :(得分:1)

使用np.append()可以轻松优雅地完成此操作。例如:

import numpy as np
a = np.zeros((8,3,4))
a = np.append(a,np.ones((8,3,1)),axis=2)

事实上,如果你想要一般方法:

import numpy as np
a = np.zeros((b,c,4))
a = np.append(a,np.ones((b,c,1)),axis=2)

如果你想要数字C而不是1,你可以将np.ones()与那个数字C相乘。 希望这有帮助!

答案 3 :(得分:1)

您可以使用np.pad

width = ((0,0),(0,0),(0,1))
np.pad(a, width, 'constant', constant_values=1.)