通常,当我们知道应该在哪里插入newaxis时,我们可以a[:, np.newaxis,...]
。有没有什么好方法可以在某个轴上插入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]
答案 0 :(得分:3)
可以将单个维度(dim length = 1)
作为形状标准添加到原始数组形状np.insert
,从而直接更改其形状,如此 -
x.shape = np.insert(x.shape,axis,1)
好吧,我们不妨扩展这个以邀请多个np.diff
和np.cumsum
技巧的新轴,就像这样 -
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)
答案 1 :(得分:1)
np.insert
slobj = [slice(None)]*ndim
...
slobj[axis] = slice(None, index)
...
new[slobj] = arr[slobj2]
与您一样,它构建切片列表,并修改一个或多个元素。
apply_along_axis
构造一个数组,并将其转换为索引元组
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_dims
In [1090]: np.expand_dims(x,2).shape
Out[1090]: (3, 2, 1, 4)
它像你一样使用reshape
,但是使用元组连接创建新形状。
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:])
蒂姆斯并没有告诉我哪个更好。它们是2μs的范围,简单地将代码包装在函数中会产生影响。