【问题标题】:Mapping a numpy array pairwise成对映射一个numpy数组
【发布时间】:2013-01-18 07:49:37
【问题描述】:

我目前正在使用 python 和 numpy/scipy 实现节拍检测算法。 我基本上需要读取一个 .wav 文件并对其进行处理。代码如下:

sampling_rate, wave_data = scipy.io.wavfile.read(argv[1])

wave_data 是一个一维 numpy 数组,包含大约 441 000 个元素(10 秒的声音,采样率为 44.1 kHz)。现在,我需要对这个数组中的每两个元素做一些基本的数学运算。这就是我现在的做法:

wave_data = [sampling_rate * (wave_data[i+1] - wave_data[i]) 
             for i in xrange(len(wave_data)-1)]

此操作需要太多时间(无需分析即可发现)。我需要成对地“就地”映射数组,而不创建新的 python 列表。我知道有numpy.vectorize,但我不知道如何进行成对映射(映射数组的每两个元素)。

【问题讨论】:

    标签: python arrays numpy mapping scipy


    【解决方案1】:

    以下任何一种都可以:

    wave_date = sampling_rate * np.diff(wave_data)
    

    wave_date = sampling_rate * (wave_data[1:] - wave_data[:-1])
    

    例如:

    In [7]: sampling_rate = 2
    
    In [8]: wave_data = np.array([1, 3, 5, 2, 8, 10])
    
    In [9]: sampling_rate * (wave_data[1:] - wave_data[:-1])
    Out[9]: array([ 4,  4, -6, 12,  4])
    

    就性能而言,这两种方法都比列表理解快约 500 倍:

    In [16]: wave_data = np.array([1., 3, 5, 2, 8, 10, 5, 2, 4, 7] * 44100)
    
    In [17]: %timeit sampling_rate * np.diff(wave_data)
    100 loops, best of 3: 2.2 ms per loop
    
    In [18]: %timeit sampling_rate * (wave_data[1:] - wave_data[:-1])
    100 loops, best of 3: 2.15 ms per loop
    
    In [19]: %timeit [sampling_rate * (wave_data[i+1] - wave_data[i]) for i in xrange(len(wave_data)-1)]
    1 loops, best of 3: 970 ms per loop
    

    【讨论】:

    • 我认为您应该提到wave_date[1:]wave_date[:-1] 将为现有数组创建视图,因此它们不会消耗太多内存。即使它们的差异确实创建了一个新数组。
    • 工作让我变成了一个内存管理狂,所以我可能会选择wave_data[1:] -= wave_data[:-1]; wave_data *= sampling_rate; wave_data = wave_data[:-1],它实际上也可能稍微快一些,因为不需要创建数组。
    猜你喜欢
    • 2020-07-19
    • 1970-01-01
    • 1970-01-01
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    • 2021-01-29
    • 2018-06-10
    • 1970-01-01
    相关资源
    最近更新 更多