在 for 循环中使用 2D 数组构建 3D 数组

Using 2D arrays to build a 3D array in for loop

我正在尝试定义一个函数:

  1. 从目录中读取每个 1 分钟的音频文件
  2. 计算每个 1 分钟文件的每秒特征,return为每个文件计算形状为 (60, 96, 64) 的 numpy 数组 feats,其中 60 表示每秒
  3. 将 1 分钟文件中所有秒数的平均值计算为 return features_from_one_file 形状 (96, 64)
  4. 的数组
  5. 将这些均值数组中的每一个附加到 3D 数组 features_allfiles,以便每个 1 分钟的文件在 features_allfiles 中表示为一个维度(正确的术语?)。例如,如果使用了五个 1 分钟的文件,则其形状为 (5, 96, 64)
  6. 然后我的目标是对此进行调整,以便任何长度为 n 分钟的文件的 feats 数组将被 n 分割,以便平均每分钟 return 编辑。

我卡在了第四步,所以可以寻求帮助,也欢迎对第 5 步提出任何建议!

到目前为止,这是我的代码:

def get_features(directory):
audio_fs = os.listdir(directory) #list of all files in directory

features_allfiles = np.empty([0,96,64])

for f in audio_fs:
    #find file:
    path = os.path.join(directory, f)
    
    #calculate features from audio file:
    feats = vggish_input.wavfile_to_examples(path)
    print(np.shape(feats))                    #this returns (62, 96, 64) for a 1min file
    
    #Get the mean of the these 62 2D arrays
    features_from_one_file = np.mean(feats, axis = 0) 
    print(np.shape(features_from_one_file))   #this returns (96, 64)
    
    #Append the mean of each file to features_allfiles, so that it has shape (n, 96, 62), where n = number of files
    ???
    
return features_allfiles

您可以使用 np.vstack 但首先您必须向 features_from_one_file 添加一个新维度:


编辑

As suggested @hpaulj, the best practice is to stack only once, so you need to collect all `features_from_one_file` in a list and then stack them:

import numpy as np

all_feats = []
for i in range(5):
    #create features    
    features_from_one_file = np.random.randn(96,64)
    #append Broadcasting first to have dimension 1x96x64
    all_feats.append(features_from_one_file[None,:] )

#stack all at once
features_allfiles = np.vstack(all_feats)

print(features_allfiles.shape)

输出

(5, 96, 64)

旧提议:逐一堆叠(这样比较慢)


features_allfiles = np.empty([0,96,64])

for i in range(5):
    #new features
    features_from_one_file = np.random.randn(96,64)
    
    #vertical stack, [None,:] recast array adding new dimension first
    # you can also use features_from_one_file.reshape(1,96,64)
    features_allfiles = np.vstack([features_allfiles,
                                   features_from_one_file[None,:]])


print(features_allfiles.shape)

输出

(5, 96, 64)