Numpy 用广播机制扩展数组

你也许还不了解广播机制这个术语,就已经把它应用到数组运算过程中了。简而言之,NumPy总是试图完成运算,即便运算对象的形状并不匹配。本攻略中,我们将把一个数组和一个标量相乘。标量会被“扩展”为和数组对象相同的形状,然后与之相乘。我们将下载一个声音文件,然后为它创建一个音量减小的新版本。

具体步骤

从读取一个WAV文件开始,步骤如下。

  1. 读取一个WAV文件。
    我们使用标准的Python代码,下载一个声音文件,其内容是Austin Powers演唱的歌曲“Smashing, baby”。SciPy有一个wavefile模块,用来加载声音数据或生成WAV文件。如果SciPy已经安装,我们就可以使用该模块。read函数返回一个包含声音数据的数组和采样率。本例中我们只关心声音数据。
sample_rate, data = scipy.io.wavfile.read(WAV_FILE)
  1. 画出原始的WAV数据。
    用Matplotlib画出原始的WAV数据,并把这个子图的标题命名为Original。
matplotlib.pyplot.subplot(2, 1, 1)
matplotlib.pyplot.title("Original")
matplotlib.pyplot.plot(data)
  1. 创建一个新的数组。
    我们用NumPy创建一个音量减小的声音样本。其实就是把原始的声音数据数组与一个常数相乘,生成一个数据值减小的新数组,广播机制的魔力就体现在这里。最后,为了能生成WAV格式的文件,我们需要确保新数组的数据类型与原始数组一致。
newdata = data * 0.2
newdata = newdata.astype(numpy.uint8)
  1. 生成新的WAV文件。
    把新数组写入到一个新的WAV文件中,如下所示。
scipy.io.wavfile.write("quiet.wav",
    sample_rate, newdata)
  1. 画出新的WAV数据。
    用Matplotlib画出新数组。
matplotlib.pyplot.subplot(2, 1, 2)
matplotlib.pyplot.title("Quiet")
matplotlib.pyplot.plot(newdata)

matplotlib.pyplot.show()

最终结果如下图所示,两个子图分别对应原始的WAV文件和数值按比例缩小后的新数组。

用广播机制扩展数组

本攻略的完整代码如下。

import scipy.io.wavfile
import matplotlib.pyplot
import urllib2
import numpy

response = urllib2.urlopen('http://www.thesoundarchive.com/
austinpowers/smashingbaby.wav')
print response.info()
WAV_FILE = 'smashingbaby.wav'
filehandle = open(WAV_FILE, 'w')
filehandle.write(response.read())
filehandle.close()
sample_rate, data = scipy.io.wavfile.read(WAV_FILE)
print "Data type", data.dtype, "Shape", data.shape

matplotlib.pyplot.subplot(2, 1, 1)
matplotlib.pyplot.title("Original")
matplotlib.pyplot.plot(data)

newdata = data * 0.2
newdata = newdata.astype(numpy.uint8)
print "Data type", newdata.dtype, "Shape", newdata.shape

scipy.io.wavfile.write("quiet.wav",
    sample_rate, newdata)

matplotlib.pyplot.subplot(2, 1, 2)
matplotlib.pyplot.title("Quiet")
matplotlib.pyplot.plot(newdata)

matplotlib.pyplot.show()

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程