我有一个Python函数,给定标量或向量a
,它可以进行某种对称扩展,例如,
import numpy
def expand(a):
zero = numpy.zeros_like(a)
return numpy.array([
[zero, a, a],
[a, zero, a],
[a, a, zero],
#
[zero, -a, -a],
[-a, zero, -a],
[-a, -a, zero],
])
在此示例中,所得数组将具有形状(6, 3, a.shape)
。最终,我需要(6, a.shape, 3)
或(3, a.shape, 6)
的形状和连续性,所以我需要numpy.moveaxis()
周围。甚至(3, 6, a.shape)
也会有所改善。我可以用
import numpy
def expand(a):
zero = numpy.zeros_like(a)
return numpy.array([
[zero, a, a, zero, -a, -a],
[a, zero, a, -a, zero, -a],
[a, a, zero, -a, -a, zero]
])
,但是它不如第一个版本可读,尤其是在转换更为复杂的情况下。 (总有3列。)
有没有一种方法可以初始化out
以立即具有正确的形状? (请注意,reshape()
不会这样做,数据顺序错误。)
答案 0 :(得分:2)
有没有一种方法可以初始化为正确的形状 离开吗?
是的,实际上是:只需分配所需的形状,然后根据需要在转置视图上进行初始化。由于视图是---视图-所有视图更改都会传播到原始数组,同时保持其内存布局。
import numpy
def expand(a):
zero = numpy.zeros_like(a)
out = numpy.empty((6,*a.shape,3),a.dtype)
out.transpose(0,2,1)[...] = [
[zero, a, a],
[a, zero, a],
[a, a, zero],
#
[zero, -a, -a],
[-a, zero, -a],
[-a, -a, zero],
]
return out
示例:
>>> out = expand(numpy.arange(1,3))
>>> out
array([[[ 0, 1, 1],
[ 0, 2, 2]],
[[ 1, 0, 1],
[ 2, 0, 2]],
[[ 1, 1, 0],
[ 2, 2, 0]],
[[ 0, -1, -1],
[ 0, -2, -2]],
[[-1, 0, -1],
[-2, 0, -2]],
[[-1, -1, 0],
[-2, -2, 0]]])
>>> out.flags
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : True
WRITEABLE : True
ALIGNED : True
WRITEBACKIFCOPY : False
UPDATEIFCOPY : False
答案 1 :(得分:1)
让我们尝试(3,6) + a.shape
:
def expand(a):
sub = 1-np.eye(3, dtype=int)
kernel = np.hstack([sub,-sub])
return np.multiply.outer(kernel, a)
expand(a).shape
# (3, 6, 2, 5)
现在,如果您想要(3,a.shape, 6)
,则可以执行transpose
:
def expand2(a):
sub = 1-np.eye(3, dtype=int)
kernel = np.hstack([sub,-sub])
return np.multiply.outer(kernel, a).transpose(0,2,3,1)
expand2(a).shape
# (3, 2, 5, 6)
答案 2 :(得分:0)
这是一个简单的numpy方法
>>> a = np.arange(1,3)
>>>
>>> out = np.empty((6,*a.shape,3),a.dtype)
>>> aux = out.reshape(2,3,-1,3)
>>> aux[0] = a[:,None]
>>> aux[1] = -a[:,None]
>>> np.einsum("ijkj->ijk",aux)[...] = 0
>>>
>>> out
array([[[ 0, 1, 1],
[ 0, 2, 2]],
[[ 1, 0, 1],
[ 2, 0, 2]],
[[ 1, 1, 0],
[ 2, 2, 0]],
[[ 0, -1, -1],
[ 0, -2, -2]],
[[-1, 0, -1],
[-2, 0, -2]],
[[-1, -1, 0],
[-2, -2, 0]]])
>>>
>>> out.flags
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : True
WRITEABLE : True
ALIGNED : True
WRITEBACKIFCOPY : False
UPDATEIFCOPY : False