如何在Jupyter中同时遍历多子目录处理WAV文件?
批量遍历多子目录处理WAV文件的解决方案
嘿,我懂你现在的处境——已经搞定单个子目录的WAV特征提取,现在要把这个流程扩展到所有子目录对吧?这事儿其实不难,Python里有两种很实用的方法,我给你拆解清楚,直接就能套用在你的代码上:
方法1:用os.walk遍历(传统但稳定)
os.walk会帮你递归遍历根目录下的所有子目录和文件,完美适配你的文件夹结构。我把你的代码改成多目录版本,还顺便帮你加上了类别标签存储(毕竟后续做数据建模肯定需要知道每个特征对应的音乐类型):
import os import librosa # 初始化特征存储结构,方便后续扩展更多特征 all_features = { 'zero_crossing_rate': [] # 要加其他特征直接在这里加就行,比如'mfcc': [], 'spectral_centroid': [] } genre_labels = [] # 记录每个特征对应的子目录(音乐类别) # 替换成你的实际根目录路径 root_directory = '/content/Data/genres_original/' # 开始遍历所有子目录 for current_dir, subdirs, files in os.walk(root_directory): # 跳过根目录本身,只处理子文件夹里的内容 if current_dir == root_directory: continue # 获取当前子目录的名称(也就是音乐类别) current_genre = os.path.basename(current_dir) # 遍历当前子目录下的所有文件 for filename in sorted(files): if filename.endswith('.wav'): # 拼接完整的文件路径,避免手动拼接出错 file_path = os.path.join(current_dir, filename) # 加载音频文件 audio_signal, sample_rate = librosa.load(file_path) # 提取零交叉率(和你原来的逻辑一致) zcr_feature = librosa.feature.zero_crossing_rate(audio_signal) all_features['zero_crossing_rate'].append(zcr_feature) # 记录这个文件对应的类别 genre_labels.append(current_genre) # 要是想加其他特征,直接在这里复制逻辑就行 # 比如提取MFCC: # mfcc_feature = librosa.feature.mfcc(y=audio_signal, sr=sample_rate) # all_features['mfcc'].append(mfcc_feature)
代码说明:
os.walk(root_directory)会返回三个值:当前遍历的目录路径、当前目录下的子目录列表、当前目录下的文件列表- 我们跳过根目录,只处理它下面的子文件夹,这样就能精准获取每个WAV文件对应的类别
- 用
os.path.join拼接路径比手动加斜杠更安全,能避免不同操作系统的路径格式问题
方法2:用pathlib遍历(更简洁现代)
如果你喜欢更优雅的路径处理,pathlib是Python 3.4+的官方推荐方案,代码会更简洁:
from pathlib import Path import librosa all_features = {'zero_crossing_rate': []} genre_labels = [] root_directory = Path('/content/Data/genres_original/') # 递归查找所有子目录下的.wav文件,sorted保证顺序和你原来的一致 for wav_file in sorted(root_directory.rglob('*.wav')): # 获取父目录名称(也就是音乐类别) current_genre = wav_file.parent.name # 直接传入Path对象给librosa,它支持这种格式 audio_signal, sample_rate = librosa.load(wav_file) zcr_feature = librosa.feature.zero_crossing_rate(audio_signal) all_features['zero_crossing_rate'].append(zcr_feature) genre_labels.append(current_genre)
代码说明:
rglob('*.wav')会递归匹配所有子目录下的WAV文件,省去了多层循环的麻烦Path对象自带各种路径操作方法,比如parent.name直接获取父目录名称,比os.path更直观
一些实用小贴士
- 进度可视化:如果文件数量多,建议装个
tqdm库,把循环改成for wav_file in tqdm(sorted(root_directory.rglob('*.wav'))),就能看到实时处理进度了 - 特征维度统一:不同音频的长度可能不一样,提取的特征维度会有差异,后续建模前可以考虑对每个特征取均值、最大值,或者裁剪/补全到固定长度
- 数据保存:处理完的特征和标签可以用
pandas存成CSV,或者用numpy.savez保存成二进制文件,方便后续直接加载建模
内容的提问来源于stack exchange,提问作者Dario_Della
相关产品推荐
相关产品推荐

