如何读取多文件生成指定形状的NumPy二维数组?
问题描述
需要读取多个文件并将数据填充到数组中,让数组的每一行对应一个文件的数据,但无法预先知晓每个文件的数据点数。
此前读取单个文件的实现很简单:
timestep = np.array([]) time = np.array([]) with open('time-series.dat') as f: for line in f: ele = line.rstrip("\n").split() timestep = np.append(timestep,float(ele[0])) time = np.append(time,float(ele[1]))
此时timestep和time都是与数据点数等长的一维数组。
现在需要读取多个文件并生成形状为(文件数量, 每个文件的数据点数)的二维数组,初步框架如下:
cases = ['1','2'] timestep = np.array([]) time = np.array([]) for i in range(len(cases)): with open('time-series'+cases[i]+'.dat') as f: for line in f: ele = line.rstrip("\n").split() ??? ???
使用np.append只会得到长度为2*数据点数的一维数组,无法生成二维数组;尝试np.vstack但无法在初始空数组上使用。
曾用列表实现:通过list.append添加新行,但需要额外列表变量,且要在列表与数组间反复转换,当变量增多时会更繁琐:
cases = ['1','2'] timestep = np.array([]) time = np.array([]) for i in range(len(cases)): if i>0: timestep=timestep.tolist() time = time.tolist() arr1 = [] arr2 = [] with open('time-series'+cases[i]+'.dat') as f: for line in f: ele = line.rstrip("\n").split() arr1.append(ele[0]) arr2.append(ele[1]) timestep.append(arr1) time.append(arr2) timestep = np.array(timestep) time = np.array(time) # 这里转成numpy数组是因为需要在进入下一次循环前用timestep和time做进一步计算
不想预先查看文件确定数据点数来创建指定大小的数组,请问有没有更简便的方法实现读取多文件并生成二维数组?
解决方案
方法1:先收集所有数据到列表,最后一次性转数组(优化版)
避免循环中反复转换列表和数组,先全程用列表收集数据,若需要在循环内做计算,可先将当前文件的数据转为临时数组完成运算,再把结果加入总列表。
示例代码:
import numpy as np cases = ['1', '2'] timestep_list = [] time_list = [] for case in cases: arr1 = [] arr2 = [] with open(f'time-series{case}.dat') as f: for line in f: ele = line.rstrip("\n").split() arr1.append(float(ele[0])) arr2.append(float(ele[1])) # 单文件计算示例:求当前文件时间序列的均值 temp_timestep = np.array(arr1) temp_time = np.array(arr2) mean_time = temp_time.mean() print(f'Case {case} 时间均值:{mean_time}') # 将当前文件数据加入总列表 timestep_list.append(arr1) time_list.append(arr2) # 最后一次性转成二维numpy数组 timestep = np.array(timestep_list) time = np.array(time_list)
该方法既避免了反复转换的繁琐,又能满足循环内的计算需求,逻辑清晰且代码简洁。
方法2:用numpy的loadtxt简化文件读取
numpy的loadtxt可直接读取文本文件并生成数组,省去手动逐行解析的步骤,搭配列表收集效率更高。
示例代码:
import numpy as np cases = ['1', '2'] timestep_list = [] time_list = [] for case in cases: # 直接读取文件,按列拆分数据 data = np.loadtxt(f'time-series{case}.dat') temp_timestep = data[:, 0] temp_time = data[:, 1] # 单文件计算示例:求当前文件的最大时间步 max_timestep = temp_timestep.max() print(f'Case {case} 最大时间步:{max_timestep}') timestep_list.append(temp_timestep) time_list.append(temp_time) timestep = np.array(timestep_list) time = np.array(time_list)
loadtxt会自动处理换行和分割,代码更简洁,适合格式规范的文本文件。若文件有表头,可添加skiprows参数跳过。
注意事项
如果不同文件的数据点数不一致,用np.array转换后会得到object类型的数组(而非二维数值数组),此时可:
- 确认所有文件的数据点数是否统一(实验数据通常需要保持一致)
- 若确实存在差异,用
np.pad将短序列补全到最长长度,或继续用列表存储按需处理
内容的提问来源于stack exchange,提问作者Saurabh
相关产品推荐
相关产品推荐

