Python 在NumPy数组中的可变位置插入新轴

Python 在NumPy数组中的可变位置插入新轴,python,arrays,numpy,Python,Arrays,Numpy,通常,当我们知道应该在哪里插入newaxis时,我们可以执行a[:,np.newaxis,…]。有没有什么好方法可以在某个轴上插入新轴 下面是我现在的做法。我认为一定有比这更好的方法: def addNewAxisAt(x, axis): _s = list(x.shape) _s.insert(axis, 1) return x.reshape(tuple(_s)) def addNewAxisAt2(x, axis): ind = [slice(None)]

通常,当我们知道应该在哪里插入newaxis时,我们可以执行
a[:,np.newaxis,…]
。有没有什么好方法可以在某个轴上插入新轴

下面是我现在的做法。我认为一定有比这更好的方法:

def addNewAxisAt(x, axis):
    _s = list(x.shape)
    _s.insert(axis, 1)
    return x.reshape(tuple(_s))

def addNewAxisAt2(x, axis):
    ind = [slice(None)]*x.ndim
    ind.insert(axis, np.newaxis)
    return x[ind]

可以将单个维度
(dim length=1)
作为形状标准添加到原始数组形状,从而直接更改其形状,如下所示-

x.shape = np.insert(x.shape,axis,1)
insert_idx = (np.diff(np.append(0,axis))-1).cumsum()+1
x.shape = np.insert(x.shape,insert_idx,1)
好吧,我们不妨扩展它,用一点技巧和技巧邀请多个新轴,就像这样-

x.shape = np.insert(x.shape,axis,1)
insert_idx = (np.diff(np.append(0,axis))-1).cumsum()+1
x.shape = np.insert(x.shape,insert_idx,1)
样本运行-

In [151]: def addNewAxisAt(x, axis):
     ...:     insert_idx = (np.diff(np.append(0,axis))-1).cumsum()+1
     ...:     x.shape = np.insert(x.shape,insert_idx,1)
     ...:     

In [152]: A = np.random.rand(4,5)

In [153]: addNewAxisAt(A, axis=1)

In [154]: A.shape
Out[154]: (4, 1, 5)

In [155]: A = np.random.rand(5,6,8,9,4,2)

In [156]: addNewAxisAt(A, axis=5)

In [157]: A.shape
Out[157]: (5, 6, 8, 9, 4, 1, 2)

In [158]: A = np.random.rand(5,6,8,9,4,2,6,7)

In [159]: addNewAxisAt(A, axis=(1,3,4,6))

In [160]: A.shape
Out[160]: (5, 1, 6, 1, 1, 8, 1, 9, 4, 2, 6, 7)

np.insert
does

slobj = [slice(None)]*ndim
...
slobj[axis] = slice(None, index)
...
new[slobj] = arr[slobj2]
与您一样,它构造一个切片列表,并修改一个或多个元素

沿_轴应用_
构造一个数组,并将其转换为索引元组

outarr[tuple(i.tolist())] = res
其他numpy函数也是这样工作的

我的建议是使初始列表足够大,以容纳
None
。那么我就不需要使用
insert

In [1076]: x=np.ones((3,2,4),int)

In [1077]: ind=[slice(None)]*(x.ndim+1)

In [1078]: ind[2]=None

In [1080]: x[ind].shape
Out[1080]: (3, 2, 1, 4)

In [1081]: x[tuple(ind)].shape   # sometimes converting a list to tuple is wise
Out[1081]: (3, 2, 1, 4)
结果是有一个
np.expand\u dims

In [1090]: np.expand_dims(x,2).shape
Out[1090]: (3, 2, 1, 4)
它像您一样使用
重塑
,但使用元组连接创建新形状

def expand_dims(a, axis):
    a = asarray(a)
    shape = a.shape
    if axis < 0:
        axis = axis + len(shape) + 1
    return a.reshape(shape[:axis] + (1,) + shape[axis:])
def expand_dims(a,轴):
a=a阵列(a)
形状
如果轴<0:
轴=轴+透镜(形状)+1
返回a.重塑(形状[:轴]+(1,)+形状[轴:)

时间并不能告诉我哪个更好。它们是2µs的范围,简单地将代码包装到函数中就会产生不同。

哦,当然!很容易忘记ndarray的形状是一个可设置的属性。还有
numpy.reformate
,它可以以一种非变异的方式完成此操作。@user2357112是的!使用
np输出的新形状信息。从代码中插入
。@Divakar非常感谢!由于有内置的
np.expand_dims
,我接受了内置版本的答案。