用较短数组替换numpy一维数组的一部分
我有一个一维的numpy数组,里面存放了一些音频数据。我正在处理这些数据,想把某些部分替换成白噪声。不过,这个噪声的长度要比被替换的部分短。生成噪声没问题,但我在想,怎么才能简单地把原来的数据替换成噪声呢?我最开始想到用 data[10:110] = noise[0:10]
来替换,但这样做不行,因为它们的尺寸不匹配。
有什么简单的方法可以把numpy数组的一部分替换成另一部分,且这两部分的尺寸不同吗?
补充说明:这些数据是未压缩的PCM音频数据,最长可以达到一个小时,可能占用几百MB的内存。我希望避免在内存中创建额外的副本。
2 个回答
我对numpy不是很熟悉,但你是不是可以把数据数组分成和噪声数组一样大小的小块,然后把每个数据小块设置成对应的噪声小块?比如说:
data[10:20] = noise[0:10]
data[21:31] = noise[0:10]
等等,类似的?
你可以这样循环:
for x in range(10,100,10):
data[x:10+x] = noise[0:10]
更新:
如果你想缩短原始数据数组,可以这样做:
data = data[:10] + noise[:10]
这样会截断数据数组,并在第10个位置后把噪声加到原始数组里。如果需要的话,你可以把剩下的数据数组添加到新数组中。
在你的应用中,numpy数组相比于python列表有什么好处呢?我觉得numpy数组的一个缺点是它们不容易调整大小:
http://mail.python.org/pipermail/python-list/2008-June/1181494.html
你真的需要回收你缩短的数组部分的内存吗?如果不需要,也许你可以使用掩码数组:
http://docs.scipy.org/doc/numpy/reference/maskedarray.generic.html
当你想用一段更短的噪声替换信号的一部分时,先替换信号的第一部分,然后将剩下被移除的信号部分遮蔽掉。
编辑:这里有一些笨拙的numpy代码,它没有使用掩码数组,也没有分配更多的内存。同时,它也没有释放被删除部分的内存。这个想法是通过移动数组的其余部分来替换你想删除的数据,最后留下零(或者垃圾数据)在数组的末尾。
import numpy
a = numpy.arange(10)
# [0 1 2 3 4 5 6 7 8 9]
## Replace a[2:7] with length-2 noise:
insert = -1 * numpy.ones((2))
new = slice(2, 4)
old = slice(2, 7)
#Just to indicate what we'll be replacing:
a[old] = 0
# [0 1 0 0 0 0 0 7 8 9]
a[new] = insert
# [0 1 -1 -1 0 0 0 7 8 9]
#Shift the remaining data over:
a[new.stop:(new.stop - old.stop)] = a[old.stop:]
# [0 1 -1 -1 7 8 9 7 8 9]
#Zero out the dangly bit at the end:
a[(new.stop - old.stop):] = 0
# [0 1 -1 -1 7 8 9 0 0 0]