接触python时间不长,也就看了最基础的语法,并且几乎没有其他语言基础。因为实验室要做项目,现在要实现一个算法,其中涉及到S变换,没有找到合适的开源项目可以直接调用。所以想根据公式自己实现,根据文献的公式,如果直接写需要四重for loop,为了降低复杂度,想尽量向量化。而故事也就是这时候发生了。
由于语音信号分帧,所以进行S变换时需要引入3维矩阵,本着(N*N*nf)是以nf为帧的索引进行操作时,在进行一系列操作之后发现,numpy有一些致命的操作,如果没有仔细了解过一般都会入坑的感觉。
请看,
C = np.array([[[1,2],[3,4],[5,6]],[[7,8,],[9,10],[11,12]],[[13,14],[15,16],[17,18]]])
运行结果
C
array([[[ 1, 2],
[ 3, 4],
[ 5, 6]],
[[ 7, 8],
[ 9, 10],
[11, 12]],
[[13, 14],
[15, 16],
[17, 18]]])
为了想以一些试验来确定自己实现算法时的操作能不能成功(其实就是想,同时给每一帧的第k列进行赋值),以下是一些试验
D = np.zeros((3,2,3))
你猜会是什么结果?
D
array([[[0., 0., 0.],
[0., 0., 0.]],
[[0., 0., 0.],
[0., 0., 0.]],
[[0., 0., 0.],
[0., 0., 0.]]])
出结果时,我也没有注意,接着就进行之后的操作(实际上,这时的矩阵维度和我想要的并不一致)
D[:,1,:] = C[:,0,:]
Traceback (most recent call last):
File "<pyshell#12>", line 1, in <module>
D[:,1,:] = C[:,0,:]
ValueError: could not broadcast input array from shape (3,2) into shape (3,3)
???啊?怎么回事?这时回去查看才发现矩阵维度的问题!!!
原来numpy中3维矩阵的第一维索引的是帧数…然后是行,最后是列
接下来的一些试验如下:
>>> D = np.zeros((2,3,3))
>>> D
array([[[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]],
[[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]]])
>>> np.zeros((3,3,2))
array([[[0., 0.],
[0., 0.],
[0., 0.]],
[[0., 0.],
[0., 0.],
[0., 0.]],
[[0., 0.],
[0., 0.],
[0., 0.]]])
>>> D[:,1,:] = C[:,0,:]
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
D[:,1,:] = C[:,0,:]
ValueError: could not broadcast input array from shape (3,2) into shape (2,3)
>>> C[:,0,:]
array([[ 1, 2],
[ 7, 8],
[13, 14]])
>>> E=np.zeros((3,2))
>>> E
array([[0., 0.],
[0., 0.],
[0., 0.]])
>>> C[:,0,:] = E
>>> C
array([[[ 0, 0],
[ 3, 4],
[ 5, 6]],
[[ 0, 0],
[ 9, 10],
[11, 12]],
[[ 0, 0],
[15, 16],
[17, 18]]])
>>> C[1,:,:]
array([[ 0, 0],
[ 9, 10],
[11, 12]])
>>> C[:,:,0]
array([[ 0, 3, 5],
[ 0, 9, 11],
[ 0, 15, 17]])
由矩阵E对C的赋值操作可以看到,可以同时对各帧对应矩阵的第一(对应索引0)行批量赋值;
同时,由最后一个索引操作C[:,:,0]
的结果知道,这实际上是将各帧的第一(对应索引0)列转置成行向量然后纵向堆叠(以行的方式向下堆叠)得到的新矩阵。