使用asammdf读取.dat文件转DataFrame时遇内存错误求助
解决asammdf读取大.dat文件转DataFrame时的内存错误
你的问题是一次性加载全量MDF数据到DataFrame时,因数据量过大(332列×220万行,float64类型需5.46GiB内存)导致内存不足。以下是针对MDF文件的专属解决方案:
1. 只加载需要的通道
大部分场景下不需要分析所有通道,仅提取目标通道能大幅减少内存占用:
import asammdf import pandas as pd # 替换为你实际需要分析的通道名称 target_channels = ["Speed", "EngineTorque", "FuelConsumption"] mdf = asammdf.MDF(r"C:\Users\hsr4ban\Desktop\16_MC Dynamic.dat") # 过滤出指定通道 filtered_mdf = mdf.filter(target_channels) # 转换为DataFrame df = filtered_mdf.to_dataframe()
2. 降低数据精度
将float64类型转为float32,内存占用直接减半(float32仅占4字节/元素):
import asammdf import pandas as pd mdf = asammdf.MDF(r"C:\Users\hsr4ban\Desktop\16_MC Dynamic.dat") df = mdf.to_dataframe() # 批量转换所有float64列到float32 float64_cols = df.select_dtypes(include=["float64"]).columns df = df.astype({col: "float32" for col in float64_cols})
3. 按时间区间分块处理
将数据按时间切片拆分,逐个处理小数据块,避免一次性加载全量数据:
import asammdf import pandas as pd import matplotlib.pyplot as plt mdf = asammdf.MDF(r"C:\Users\hsr4ban\Desktop\16_MC Dynamic.dat") start_time = mdf.start_time end_time = mdf.end_time # 拆分时间为4个连续区间(可根据需求调整数量) time_splits = pd.date_range(start=start_time, end=end_time, periods=4) # 逐个处理每个时间块 for idx in range(len(time_splits) - 1): # 提取当前时间区间的数据 chunk_mdf = mdf.filter_time([time_splits[idx], time_splits[idx+1]]) chunk_df = chunk_mdf.to_dataframe() # 在这里对当前块做分析/绘图,无需保存所有块到内存 chunk_df.plot(y="Speed", title=f"Data from {time_splits[idx]} to {time_splits[idx+1]}") plt.show()
4. 先导出为CSV再分块读取
如果需要保留全量数据,可先通过asammdf导出为CSV,再用pandas分块加载:
import asammdf import pandas as pd mdf = asammdf.MDF(r"C:\Users\hsr4ban\Desktop\16_MC Dynamic.dat") # 导出全量或过滤后的通道到CSV mdf.export(r"C:\Users\hsr4ban\Desktop\mdf_data.csv", format="csv") # 用pandas分块读取CSV,每块10万行(可调整) chunk_size = 100000 for chunk in pd.read_csv(r"C:\Users\hsr4ban\Desktop\mdf_data.csv", chunksize=chunk_size): # 处理当前数据块 print(f"Processing chunk with {len(chunk)} rows")
内容的提问来源于stack exchange,提问作者RanjanN
相关产品推荐
相关产品推荐

