Python3如何按文件名ID自动合并指定文件夹下所有.pkl文件到单个文件
.pkl文件按ID排序合并实现方案
方案1:全量合并(适合文件量不大、首次合并场景)
直接遍历所有.pkl文件,按ID排序后一次性合并,代码如下:
import os import pickle # 配置参数 PKL_FOLDER = "./signature" # 你的pkl存放文件夹 OUTPUT_PATH = "./merged.pkl" # 合并后输出路径 # 1. 筛选所有pkl文件 pkl_files = [f for f in os.listdir(PKL_FOLDER) if f.endswith(".pkl")] # 2. 提取文件名中的数字ID,按数字排序 def get_file_id(file_name): # 去掉.pkl后缀,转成整数 return int(os.path.splitext(file_name)[0]) sorted_pkl_files = sorted(pkl_files, key=get_file_id) # 3. 依次读取所有pkl内容合并 merged_data = [] for file in sorted_pkl_files: file_path = os.path.join(PKL_FOLDER, file) with open(file_path, "rb") as f: data = pickle.load(f) # 如果你每个pkl里是多个对象可以用extend,单个就用append merged_data.append(data) # 4. 保存合并后的pkl with open(OUTPUT_PATH, "wb") as f: pickle.dump(merged_data, f)
方案2:增量合并(适合每日更新场景,避免重复合并)
新增记录文件保存上次合并的最大ID,每次只合并新增的文件,效率更高:
import os import pickle PKL_FOLDER = "./signature" OUTPUT_PATH = "./merged.pkl" LAST_ID_RECORD = "./last_merged_id.txt" # 记录上次合并到的ID # 1. 读取上次合并到的最大ID last_id = 0 if os.path.exists(LAST_ID_RECORD): with open(LAST_ID_RECORD, "r") as f: last_id = int(f.read().strip()) # 2. 筛选所有大于上次ID的pkl文件,排序 pkl_files = [f for f in os.listdir(PKL_FOLDER) if f.endswith(".pkl")] def get_file_id(file_name): return int(os.path.splitext(file_name)[0]) new_pkl_files = [f for f in pkl_files if get_file_id(f) > last_id] sorted_new_files = sorted(new_pkl_files, key=get_file_id) if not sorted_new_files: print("无新增文件,无需合并") exit() # 3. 读取原有合并文件(如果存在),追加新数据 merged_data = [] if os.path.exists(OUTPUT_PATH): with open(OUTPUT_PATH, "rb") as f: merged_data = pickle.load(f) for file in sorted_new_files: file_path = os.path.join(PKL_FOLDER, file) with open(file_path, "rb") as f: merged_data.append(pickle.load(f)) # 4. 保存新的合并文件和最新的最大ID with open(OUTPUT_PATH, "wb") as f: pickle.dump(merged_data, f) new_max_id = get_file_id(sorted_new_files[-1]) with open(LAST_ID_RECORD, "w") as f: f.write(str(new_max_id))
注意事项
- 如果你的.pkl文件存储的是Pandas DataFrame,读取后可以直接用
pd.concat()合并,无需手动拼接列表 - 排序逻辑必须将文件名提取为整数后再排序,直接对文件名字符串排序会出现
10.pkl排在2.pkl前面的错误 - 如果文件总量超过内存承载上限,可以将合并后的结果分块存储,或者改用Parquet等更适合批量存储的序列化格式
内容的提问来源于stack exchange,提问作者renaldyks
相关产品推荐
相关产品推荐

