【问题标题】:Replace part of numpy 1D array with shorter array用较短的数组替换部分 numpy 1D 数组
【发布时间】:2010-12-20 15:19:11
【问题描述】:

我有一个包含一些音频数据的一维 numpy 数组。我正在做一些处理,想用白噪声替换数据的某些部分。然而,噪音应该比更换的部件短。产生噪声不是问题,但我想知道用噪声替换原始数据的最简单方法是什么。由于明显的尺寸不匹配,我第一次想到做data[10:110] = noise[0:10] 不起作用。

用不同维度的另一部分替换 numpy 数组的一部分的最简单方法是什么?

编辑: 数据是未压缩的 PCM 数据,最长可达一小时,占用数百 MB 内存。我想避免在内存中创建任何额外的副本。

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:

    对于您的应用程序,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]
    

    【讨论】:

    • 我用来读取音频数据的库返回一个 numpy 数组。此外,数据大小为数百兆字节,因此我认为在这种情况下使用普通列表的开销会非常大。
    • 好的,我添加了一种用更短的数组替换部分数组的方法。
    【解决方案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 个位置之后的原始数组中,如果需要,您可以将其余数据数组添加到新数组中。

    【讨论】:

    • 我可能不清楚。我不想重复噪音。我想删除原始数据,而是加入噪音。操作后原始数组应该比开始时短,因为噪声部分比替换部分短。
    • 检查我的更新,也许我不完全理解这个问题。但是看看,让我知道。
    • 谢谢,这正是我需要的。但我认为这将创建一个全新的数组,这将浪费内存,因为它与原始数据几乎相同。
    • 其实,现在我想起来了,你可以直接覆盖原来的数据数组。不会浪费内存。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-28
    • 1970-01-01
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    相关资源
    最近更新 更多