Nic*_*mer 5 python arrays numpy
我有一个复数值的 NumPy 数组,我想将其转换为一个连续的 NumPy 数组,其中实部和虚部分开。
这个
import numpy
u = numpy.array([
1.0 + 2.0j,
2.0 + 4.0j,
3.0 + 6.0j,
4.0 + 8.0j
])
u2 = numpy.ascontiguousarray(numpy.vstack((u.real, u.imag)).T)
Run Code Online (Sandbox Code Playgroud)
可以解决问题,但是转置、vstacking和转换为连续数组可能需要一两步。
是否有本机 NumPy 函数可以为我执行此操作?
Nic*_*mer 12
我使用perfplot比较了建议的解决方案。对于大矢量尺寸,恒定时间视图
u.view("(2,)float")
Run Code Online (Sandbox Code Playgroud)
确实是最快的变体。对于较小的n,
numpy.column_stack([u.real, u.imag])
Run Code Online (Sandbox Code Playgroud)
可能是最好的(最干净、最快)的选择。
重现情节的代码:
import numpy
import perfplot
def setup(n):
return numpy.random.rand(n) + 1j * numpy.random.rand(n)
def column_stack(u):
return numpy.column_stack([u.real, u.imag])
def dstack(u):
return numpy.dstack((u.real, u.imag))[0]
def concatenate(u):
return numpy.concatenate(
(numpy.array(u.real, ndmin=2).T, numpy.array(u.imag, ndmin=2).T), axis=1
)
def stack(u):
return numpy.stack((u.real, u.imag), -1)
def view(u):
return u.view("(2,)float")
perfplot.save(
"out.png",
setup=setup,
kernels=[column_stack, dstack, concatenate, stack, view],
n_range=[2 ** k for k in range(22)],
)
Run Code Online (Sandbox Code Playgroud)
您可以使用column_stack和堆叠两个一维数组作为列来制作单个二维数组。
In [9]: np.column_stack((u.real,u.imag))
Out[9]:
array([[ 1., 2.],
[ 2., 4.],
[ 3., 6.],
[ 4., 8.]])
Run Code Online (Sandbox Code Playgroud)
没有任何替代方案是native或保存在重塑、转置等方面。
例如,在内部column_stack将其输入转换为二维“列”数组。有效地它正在做
In [1171]: np.concatenate((np.array(u.real,ndmin=2).T,np.array(u.imag,ndmin=2).T),axis=1)
Out[1171]:
array([[ 1., 2.],
[ 2., 4.],
[ 3., 6.],
[ 4., 8.]])
Run Code Online (Sandbox Code Playgroud)
vstack将其输入传递给atleast_2d(m),确保每个输入都是 1 行二维数组。 np.dstack使用atleast_3d(m).
一个新函数是 np.stack
In [1174]: np.stack((u.real,u.imag),-1)
Out[1174]:
array([[ 1., 2.],
[ 2., 4.],
[ 3., 6.],
[ 4., 8.]])
Run Code Online (Sandbox Code Playgroud)
它使用None索引来校正连接的维度;有效地:
np.concatenate((u.real[:,None],u.imag[:,None]),axis=1)
Run Code Online (Sandbox Code Playgroud)
所有最终都使用np.concatenate; 它并且np.array是唯一编译的连接函数。
另一个技巧是使用 view
In [1179]: u.view('(2,)float')
Out[1179]:
array([[ 1., 2.],
[ 2., 4.],
[ 3., 6.],
[ 4., 8.]])
Run Code Online (Sandbox Code Playgroud)
复数值保存为 2 个相邻的浮点数。因此,可以将相同的数据缓冲区视为纯浮点数,或者将此视图视为 2d 浮点数数组。与concatenate函数相反,这里没有复制。
对替代方案的另一个测试是问当u2d 或更高时会发生什么?