将3d数组更改为4d数组numpy

nzk0hqpo  于 2023-01-13  发布在  其他
关注(0)|答案(2)|浏览(225)

从下面的代码中,我得到了形状为(20,1,12060)的“log_spectgrams”。我想把形状改为(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)。

icnyk63a

icnyk63a1#

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将自行计算缺少的维度

2ul0zpep

2ul0zpep2#

假设输入为(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)或@亚尔的答案可能更直接,这种解决方案只是扩展到轴大小不同于1的其他问题。

相关问题