将含时间索引的.dat文件导入为Pandas DataFrame并规整格式
将含时间索引的.dat文件导入为Pandas DataFrame并规整格式
我来帮你解决这个问题!你的.dat文件是按时间块组织的,每个块开头标注了t值,要把所有数据合并成带时间列的DataFrame,咱们一步步来:
先说说你原来代码的问题
StringIO用法错误:StringIO()需要传入文件内容的字符串,而不是文件名,直接传filename会导致读取失败;- 分隔符设置不对:你的数据是用空格分隔的,不是制表符
\t,应该用sep='\s+'匹配任意数量的空白; - 丢失时间信息:原代码没有处理每个块开头的
t值,导致最终DataFrame缺少时间维度。
解决方案一:逐行读取处理(直观易懂)
这种方法适合小文件,逻辑清晰,容易调试:
import pandas as pd # 替换成你的.dat文件路径 file_path = "your_data.dat" # 初始化存储数据的列表和当前时间变量 all_data = [] current_time = None # 逐行读取文件 with open(file_path, "r") as f: for line in f: stripped_line = line.strip() # 跳过空行 if not stripped_line: continue # 识别时间行,提取t值 if stripped_line.startswith("# t="): # 拆分字符串获取时间数值,转成整数 current_time = int(stripped_line.split("=")[1].strip()) else: # 拆分数据行,按空白分割 row_data = stripped_line.split() # 把当前时间加到行数据开头 full_row = [current_time] + row_data all_data.append(full_row) # 构建DataFrame并设置列名 df = pd.DataFrame( all_data, columns=["t", "pos", "ux", "uy", "uz", "rho"] ) # 转换数据类型(pos是整数,其余是浮点数) df["pos"] = df["pos"].astype(int) df[["ux", "uy", "uz", "rho"]] = df[["ux", "uy", "uz", "rho"]].astype(float) # 查看结果 print(df.head())
解决方案二:用Pandas批量处理(适合大文件)
如果你的文件很大,用Pandas的内置方法效率更高:
import pandas as pd file_path = "your_data.dat" # 读取所有行,不跳过注释,用空白分割,无表头 raw_df = pd.read_csv( file_path, sep="\s+", comment=None, header=None, skip_blank_lines=True ) # 找出所有时间行(第一列是#的行) time_rows = raw_df[raw_df[0] == "#"] # 提取所有时间值 time_values = time_rows[2].astype(int).tolist() # 分割每个时间对应的数据块并添加时间列 data_blocks = [] start_idx = 0 for t in time_values: # 找到下一个时间行的索引 next_time_idx = raw_df[(raw_df[0] == "#") & (raw_df.index > start_idx)].index.min() # 如果是最后一个块,直接取到末尾 if pd.isna(next_time_idx): next_time_idx = len(raw_df) # 提取当前时间块的数据,排除时间行 block = raw_df.loc[start_idx+1 : next_time_idx-1].copy() block["t"] = t data_blocks.append(block) start_idx = next_time_idx # 合并所有数据块 final_df = pd.concat(data_blocks, ignore_index=True) # 重命名列并调整顺序 final_df.columns = ["pos", "ux", "uy", "uz", "rho", "t"] final_df = final_df[["t", "pos", "ux", "uy", "uz", "rho"]] # 转换数据类型 final_df["pos"] = final_df["pos"].astype(int) final_df[["ux", "uy", "uz", "rho"]] = final_df[["ux", "uy", "uz", "rho"]].astype(float) # 查看结果 print(final_df.head())
最终效果
两种方法都会得到你想要的格式:
| t | pos | ux | uy | uz | rho |
|---|---|---|---|---|---|
| 400000 | 1601 | -0.00207587 | 0.000454623 | 0.00193855 | 0.996661 |
| 400000 | 1602 | -0.0020255 | 0.000447789 | 0.00191164 | 0.996661 |
| ... | ... | ... | ... | ... | ... |
| 410000 | 1605 | -0.0018715 | 0.000426169 | 0.00182494 | 0.996659 |
备注:内容来源于stack exchange,提问作者Riri
相关产品推荐
相关产品推荐

