如何创建行数固定、列数可变的Python二维数组?二进制文件处理求助
问题描述
我是Python新手,正在处理二进制文件,想要编写程序一次性读取多组数据。已生成从SpecFiles_1到SpecFiles_10的文件名集合,每个集合包含数量不等的二进制文件名(例如SpecFiles_1包含13个文件名)。
接下来需要通过嵌套循环逐个访问这些文件名集合,在内部循环中读取二进制文件并赋值给变量,但当前代码的循环部分出现错误。无法创建一个行数固定、列数可变的二维数组来存储这些文件对象,请求提供更好的实现方法。
现有代码
SampleName_1 = '3_1' SampleName_2 = '2_1' Date = '21062023' WeightHanged_1 = np.arange(14,20.5,0.5) WeightHanged_2 = np.arange(14,20,1) Versions = np.array([1,2,3,4,5,6]) "Getting binary file names" Wseries_1 = pd.Series(WeightHanged_1).astype(str) Wseries_2 = pd.Series(WeightHanged_2).astype(str) Vseries = pd.Series(Versions).astype(str) "Sample 3_1 filenames" SpecFiles_1 = SampleName_1 + '_' + Wseries_1 + '_' + Date + '_' + Vseries[0] SpecFiles_2 = SampleName_1 + '_' + Wseries_1 + '_' + Date + '_' + Vseries[1] SpecFiles_3 = SampleName_1 + '_' + Wseries_2 + '_' + Date + '_' + Vseries[2] SpecFiles_4 = SampleName_1 + '_' + Wseries_2 + '_' + Date + '_' + Vseries[3] SpecFiles_5 = SampleName_1 + '_' + Wseries_1 + '_' + Date + '_' + Vseries[4] SpecFiles_6 = SampleName_1 + '_' + Wseries_1 + '_' + Date + '_' + Vseries[5] "Sample 2_1 filenames" SpecFiles_7 = SampleName_2 + '_' + Wseries_1 + '_' + Date + '_' + Vseries[0] SpecFiles_8 = SampleName_2 + '_' + Wseries_1 + '_' + Date + '_' + Vseries[1] SpecFiles_9 = SampleName_2 + '_' + Wseries_2 + '_' + Date + '_' + Vseries[2] SpecFiles_10 = SampleName_2 + '_' + Wseries_2 + '_' + Date + '_' + Vseries[3] fileId = np.array([]) "vary the range according to the number of SpecFiles" for x in range(1,11): for i in range (0,len('SpecFiles_'+str(x))): FileId[x,i] = open(SpecFiles_1[0],'rb')
原代码问题分析
- 手动创建10个独立的
SpecFiles_x变量,代码冗余且不易维护 - 循环中通过字符串拼接
'SpecFiles_'+str(x)访问变量的方式错误,Python无法直接通过字符串获取变量名对应的对象 - 使用numpy数组存储文件对象不合适,numpy数组更适合同构数据,而这里每组文件数量不同(列数可变)
- 循环中
len('SpecFiles_'+str(x))是计算字符串长度,不是对应文件名集合的长度,逻辑完全错误 - 未正确管理文件句柄,直接
open文件后未关闭,易导致资源泄漏
优化实现方案
改用列表容器统一管理文件名集合和读取的二进制数据,既支持可变长度的分组,又简化循环逻辑,同时用with语句自动管理文件:
import pandas as pd import numpy as np # 集中管理配置参数 samples = ['3_1', '2_1'] date = '21062023' weight_groups = [np.arange(14, 20.5, 0.5), np.arange(14, 20, 1)] versions = np.array([1, 2, 3, 4, 5, 6]) # 生成所有文件名集合,存入列表统一管理 spec_files_list = [] # 处理样本3_1的文件名 current_sample = samples[0] # 版本0、1、4、5使用第一组权重 for v_idx in [0, 1, 4, 5]: w_series = pd.Series(weight_groups[0]).astype(str) file_names = current_sample + '_' + w_series + '_' + date + '_' + str(versions[v_idx]) spec_files_list.append(file_names.tolist()) # 版本2、3使用第二组权重 for v_idx in [2, 3]: w_series = pd.Series(weight_groups[1]).astype(str) file_names = current_sample + '_' + w_series + '_' + date + '_' + str(versions[v_idx]) spec_files_list.append(file_names.tolist()) # 处理样本2_1的文件名 current_sample = samples[1] # 版本0、1使用第一组权重 for v_idx in [0, 1]: w_series = pd.Series(weight_groups[0]).astype(str) file_names = current_sample + '_' + w_series + '_' + date + '_' + str(versions[v_idx]) spec_files_list.append(file_names.tolist()) # 版本2、3使用第二组权重 for v_idx in [2, 3]: w_series = pd.Series(weight_groups[1]).astype(str) file_names = current_sample + '_' + w_series + '_' + date + '_' + str(versions[v_idx]) spec_files_list.append(file_names.tolist()) # 存储读取的二进制数据(建议直接存数据而非文件对象) binary_data = [] # 遍历所有文件名集合,读取二进制数据 for file_group in spec_files_list: group_data = [] for filename in file_group: # with语句自动关闭文件,避免资源泄漏 with open(filename, 'rb') as f: # 读取全部二进制数据,可根据需求调整读取方式(比如按字节读) data = f.read() group_data.append(data) binary_data.append(group_data) # 使用示例:访问第一组文件(原SpecFiles_1)的第一个文件数据 # print(binary_data[0][0])
优化点说明
- 用列表
spec_files_list统一管理所有文件名集合,替代10个独立变量,代码更简洁易维护 - 用循环生成文件名,减少重复代码,后续修改配置只需调整参数即可
- 使用
with语句处理文件操作,自动完成文件关闭,避免资源泄漏 - 用列表的列表存储二进制数据,天然支持每组数量不同的场景,比numpy数组更适配需求
- 直接存储读取的二进制内容,而非文件对象(文件对象长期持有易引发问题)
内容的提问来源于stack exchange,提问作者Dhyana
相关产品推荐
相关产品推荐

