python - Python librosa 错误“音频缓冲区不是 Fortran 连续的”
问题描述
我在用librosa
只是load
,stft
我遇到了错误Audio buffer is not Fortran-contiguous
我google了一下,发现我需要添加np.asfortranarray
,所以我添加了这些句子但徒劳无功。
a, sr = librosa.load("mywave.wav",sr=self.sr,mono=False)
print(a.shape) #(2, 151199)
a[0] = np.asfortranarray(a[0])# try to avoide Fortran-contiguous
a[1] = np.asfortranarray(a[1])
# but this returns error
#Audio buffer is not Fortran-contiguous. Use numpy.asfortranarray to ensure Fortran contiguity.
stft_L = librosa.stft(a[0], n_fft=self.stft_frame,hop_length= self.hop_frame, window='hann')
我第一次编写这段代码时(可能是半年前),它奏效了。
有什么解决办法吗??
解决方案
您误解了 C 与 Fortran 连续内存布局是什么,以及这意味着您可以做什么和不能做什么。例如,改变数组中一行的内存布局
a[0] = np.asfortranarray(a[0])
没有意义,因为内存布局决定了 line 是什么。
为了说明这一点,让我们看一些 Fortran 连续数据
x = np.asfortranarray(np.arange(12).reshape(3, 4))
x.flags.f_contiguous
# True
x
# array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11]])
在内部,该 2D 数组当然是线性保存的,C-/Fortran-contigouity 决定是行还是列先出现:
x.flatten('A')
# array([ 0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11])
np.asfortranarray(x).flatten('A')
# array([ 0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11])
np.ascontiguousarray(x).flatten('A')
# array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
Fortran 内存布局是列优先的,即列一起在内存中。C 内存是行优先的,即行在内存中保持在一起。
真正令人困惑的是,该数组中的视图可以是连续的,也可以不是:
x.flags.f_contiguous, x[0].flags.f_contiguous
# (True, False)
x
显然是连续的,但x[0]
不是。那是因为[0, 1, 2, 3]
在内存中不是相邻的。
你试图做什么
a = x.copy('A')
a.flags.f_contiguous, a[0].flags.f_contiguous
# (True, False)
a[0] = np.asfortranarray(a[0])
a[1] = np.asfortranarray(a[1])
a.flags.f_contiguous, a[0].flags.f_contiguous
# (True, False)
将不起作用,因为更改单行的布局没有意义。
现在出现了令人困惑的部分:如果您有一个 Fortran 连续数组并且希望第一行是 Fortran 连续的,则不能将数组更改为 Fortran 连续:
a = x.copy('A')
a = np.asfortranarray(a)
a.flags.f_contiguous, a[0].flags.f_contiguous
# (True, False)
因为列是连续的,但不是行。
相反,如果您将数组更改为 C 连续
a = x.copy('A')
a = np.ascontiguousarray(a)
a.flags.f_contiguous, a[0].flags.f_contiguous
# (False, True)
这意味着行现在是连续的。
另一种解决方案是简单地复制数据
a = x.copy('A')
a[0].copy().flags.f_contiguous
# True
因为复制会将数据写入一个新的、线性的、连续的数组中。
那么最终的解决方案呢?
a, sr = librosa.load("mywave.wav")
stft_L = librosa.stft(a[0].copy())
但是 librosa最近也取消了对连续性的需求,所以这个问题应该会在未来慢慢消失。
推荐阅读
- r - 如何在插入符号或 tidymodels 中使用 LASSO 进行嵌套交叉验证?
- r - 使用鼠标输入大型数据帧时出错
- c# - 为什么在通过 dotnet CLI 运行 ASP.NET Core 应用程序时看到项目目录名称而不是 dotnet(进程外)?
- flutter - AppBar内的后退按钮在颤动中显示黑屏
- javascript - JavaScript:垂直遍历多维数组
- python-3.x - 没有安装候选时如何将 libpcre3-dev 添加到 docker 映像 python3.8-slim
- javascript - 单击单词以选择并作为答案提交
- apache-kafka - 我如何像关系数据库一样使用 Kafka
- django - 自动将 django 中的 user_id 和 date 字段更新到数据库中
- azure - Azure Web App 和 Azure SQL Server 的 VNet 集成