在数据处理和机器学习领域,我们经常会遇到需要将多个独立的 numpy .npz 文件合并成一个统一文件的情况。.npz 文件是 numpy 提供的一种方便的归档格式,可以存储多个 numpy 数组。然而,直接使用字典的 update() 方法进行合并,往往会导致数据丢失,因为 update() 会覆盖同名键的值。本教程将详细介绍一种正确且高效的合并策略。
在合并 .npz 文件之前,了解其内部结构至关重要。一个 .npz 文件本质上是一个包含多个 NumPy 数组的压缩包,每个数组都通过一个字符串键进行标识。为了后续能够顺利合并,建议在创建独立的 .npz 文件时遵循以下约定:
使用字典结构存储数据: 将需要保存的 NumPy 数组组织成一个字典,其中键是字符串,值是对应的 NumPy 数组。
保持键名一致性: 确保所有待合并的 .npz 文件中,代表相同类型数据的数组使用相同的键名。例如,如果每个文件都有一个特征数组和一个标签数组,可以分别命名为 'features' 和 'labels'。
使用 np.savez_compressed 或 np.savez 保存:
import numpy as np # 示例数据 arr_0 = np.random.rand(10, 5) arr_1 = np.random.randint(0, 2, size=(10,)) # 将数据存储在字典中 data_to_save = {'arr_0': arr_0, 'arr_1': arr_1} # 保存为 .npz 文件,使用 **data_to_save 展开字典作为关键字参数 # np.savez_compressed 会对数据进行压缩,节省存储空间 np.savez_compressed('path/to/file/filename_1.npz', **data_to_save) # 创建并保存第二个文件 arr_0_b = np.random.rand(15, 5) arr_1_b = np.random.randint(0, 2, size=(15,)) data_to_save_b = {'arr_0': arr_0_b, 'arr_1': arr_1_b} np.savez_compressed('path/to/file/filename_2.npz', **data_to_save_b)
通过 **data_to_save 这种方式,字典的键会成为 .npz 文件内部数组的名称。
合并的核心思想是:遍历所有 .npz 文件,对于每个相同的键,收集其对应的所有数组,然后使用 np.concatenate 将这些数组沿着合适的轴拼接起来。
以下是实现这一策略的 Python 代码:
import numpy as np import os def merge_npz_files(file_list, output_filename='merged_data.npz'): """ 合并多个 .npz 文件到一个新的 .npz 文件中。 参数: file_list (list): 包含所有待合并 .npz 文件路径的列表。 output_filename (str): 合并后 .npz 文件的输出路径和名称。 """ if not file_list: print("文件列表为空,无法合并。") return # 1. 加载所有 .npz 文件 # np.load 返回一个 NpzFile 对象,可以像字典一样访问其内部数组 data_all = [np.load(fname) for fname in file_list] merged_data = {} # 2. 遍历第一个文件的所有键(假设所有文件有相同的键结构) # 对于每个键,收集所有文件中的对应数组并进行拼接 for key in data_all[0].keys(): # 收集所有文件中对应当前键的数组 # 使用 d[key] 访问 NpzFile 对象中的数组 arrays_to_concatenate = [d[key] for d in data_all] # 3. 使用 np.concatenate 拼接数组 # 默认沿轴0拼接,即在第一个维度上堆叠 try: merged_data[key] = np.concatenate(arrays_to_concatenate, axis=0) print(f"键 '{key}' 已成功合并。新形状: {merged_data[key].shape}") except ValueError as e: print(f"警告: 键 '{key}' 的数组无法合并。错误: {e}") print(f"跳过键 '{key}' 的合并。") # 如果无法合并,可以选择跳过或采取其他处理 # 例如,如果数组形状不兼容,可能需要进行 reshape 或 padding # 4. 保存合并后的数据到新的 .npz 文件 if merged_data: np.savez_compressed(output_filename, **merged_data) print(f"所有数据已成功合并并保存到 '{output_filename}'。") else: print("没有可合并的数据。") # --- 示例用法 --- if __name__ == "__main__": # 假设我们有以下文件: # 创建一些示例 .npz 文件 if not os.path.exists("temp_npz_files"): os.makedirs("temp_npz_files") for i in range(3): arr_features = np.random.rand(10 + i, 5) # 模拟不同数量的样本 arr_labels = np.random.randint(0, 2, size=(10 + i,)) data_dict = {'features': arr_features, 'labels': arr_labels} np.savez_compressed(f'temp_npz_files/data_{i}.npz', **data_dict) print(f"创建文件: temp_npz_files/data_{i}.npz (features shape: {arr_features.shape}, labels shape: {arr_labels.shape})") # 获取所有 .npz 文件名 file_names = [os.path.join("temp_npz_files", f) for f in os.listdir("temp_npz_files") if f.endswith('.npz')] file_names.sort() # 确保顺序一致 # 执行合并 merge_npz_files(file_names, 'merged_output.npz') # 验证合并结果 print("\n验证合并结果:") merged_file = np.load('merged_output.npz') for key in merged_file.keys(): print(f"合并文件中键 '{key}' 的形状: {merged_file[key].shape}") # 清理临时文件 import shutil shutil.rmtree("temp_npz_files") os.remove("merged_output.npz") print("\n清理完成。")
正确合并多个 NumPy .npz 文件的关键在于理解 .npz 文件的内部结构以及 np.concatenate 的工作原理。通过遵循一致的数据存储约定,并采用基于键的数组拼接策略,我们可以高效地将分散的数据聚合到一个统一的 .npz 文件中,为后续的数据分析和模型训练提供便利。同时,对于大规模数据集,务必考虑内存管理和性能优化。
以上就是如何高效合并多个 NumPy .npz 文件的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号