【问题标题】:Change 3d array to 4d array numpy将 3d 数组更改为 4d 数组 numpy
【发布时间】:2017-04-20 02:58:02
【问题描述】:

从下面的代码中,我得到了形状为 (20,1,12060) 的“log_specgrams”。 我想将形状更改为 (20, 60, 201, 1)。 所以我写了这样的代码。

log_specgrams = np.asarray(log_specgrams).reshape(len(log_specgrams), 60, 201, 1)

但是我报错了:

Traceback (most recent call last):
  File "D:/for-test.py", line 26, in <module>
    features = extract_features(parent_dir,sub_dirs)
  File "D:/for-test.py", line 17, in extract_features
    log_specgrams = np.asarray(log_specgrams).reshape(len(log_specgrams), 60, 201, 1)
  File "C:\Users\CHS\Anaconda3\lib\site-packages\numpy\core\numeric.py", line 482, in asarray
    return array(a, dtype, copy=False, order=order)
ValueError: could not broadcast input array from shape (12060) into shape (1)
(1, 12060)

整个代码:

import glob
import os
import librosa
import numpy as np

def extract_features(parent_dir, sub_dirs, file_ext="*.wav"):
        log_specgrams = []
        for l, sub_dir in enumerate(sub_dirs):
                for fn in glob.glob(os.path.join(parent_dir, sub_dir, file_ext)):
                        X_in, sample_rate = librosa.load(fn)
                        melspec = librosa.feature.melspectrogram(y=X_in, sr=sample_rate, n_fft=1024, hop_length=441, n_mels=60)
                        logmel = librosa.logamplitude(melspec)
                        logmel = logmel.T.flatten()[:, np.newaxis].T
                        log_specgrams.append(logmel)

        print(np.shape(logmel))
        log_specgrams = np.asarray(log_specgrams).reshape(len(log_specgrams), 60, 201, 1)
        print(np.shape(log_specgrams))
        A = features

        return np.array(log_specgrams)


parent_dir = 'Sound-Data_small'
sub_dirs= ['fold1','fold2']
features = extract_features(parent_dir,sub_dirs)

我真的很想将'log_specgrams'的形状(20,1,12060)更改为(20,60,201,1)。

【问题讨论】:

  • 该错误似乎发生在asarray 中,即在您进行重塑之前。可能log_specgrams的内容不齐?
  • 简单的reshape 有用吗?用更小的尺寸测试它,这样你就可以看到发生了什么。那个尺寸1 尺寸有什么意义?为什么要翻转位置?
  • 是的。错误发生在 asarry 中。因为我是Python的初学者,所以我不明白你的问题(同质化?)你能简单地告诉我吗?如果是“同质”,有解决办法吗?
  • 我正在对基于 CNN 的结构进行建模。我想从音频文件中提取特征并将它们用作训练数据。所以我需要形状为(特征数、宽度、高度、尺寸)的特征矩阵。我不需要多维,因为我使用音频功能。
  • 我只是说元素的形状可能不同。例如,如果您尝试将 [[1,2,3], [1,2,3], [[1,2,3],[3,4],[5,6]]] 转换为数组,它将不起作用。本质上是因为这些元素不能以矩形图案铸造。类似的事情可能会导致您的问题。

标签: python arrays numpy


【解决方案1】:

Reshape 将参数作为一个元组,即

log_specgrams = np.asarray(log_specgrams).reshape((len(log_specgrams), 60, 201, 1))

log_specgrams = np.asarray(log_specgrams).reshape((None, 60, 201, 1))

None 自己计算缺失的维度

【讨论】:

  • 感谢您的回答。不幸的是,我遇到了同样的错误。你有其他意见吗? (解决方案?)
  • 只是一个补充,reshape(-1, 60, 201, 1) 的工作方式与None 相同。
  • 事实上,在最近的 numpy (1.11.1) None 返回错误,而 -1 按预期工作。
【解决方案2】:

假设输入是 (20,1,12060) 并且期望的输出是 (20, 60, 201, 1) 并交换了 1 维度,以下应该可以正常工作:

data = np.asarray(log_specgrams)
data = data.swapaxes(1, 2).reshape(20, 60, 201, 1)

随机数据示例:

>>> data = np.random.randn(20, 1, 12060)
>>> data.shape
(20, 1, 12060)

那么,

>>> data = data.swapaxes(1, 2).reshape(20, 60, 201, 1)
>>> data.shape
(20, 60, 201, 1)

可以注意到,该操作有两个组成部分。第一部分交换第二和第三轴,将数据从(20, 1, 12060) 转换为(20, 12060, 1)。第二部分将第二个轴 12060 分成两个大小为 60 x 201 的新轴。

它适用于不同大小的任意轴,但对于不需要重新排列数据的 1 大小的轴,data.reshape(20, 60, 201, 1) 或 @yar 的答案与单个 reshape 可能更直接。这个解决方案只是扩展到轴大小不同于1的其他问题。

【讨论】:

    猜你喜欢
    • 2018-03-17
    • 2021-08-06
    • 1970-01-01
    • 2021-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多