问题描述
适用问题:在文本文档中,存在多组数据,每组数据以不固定的行数出现,但是每组包含信息的形式存在重复性;需要将每组数据提取出来。
使用脚本控制abaqus批量构建RVE模型(调用micro mechanics插件)并且使用EasyPBC添加边界约束得到E11与V12结果,完整的所有结果包含在rpy文件中,因此需要将结果信息提取出来,放入csv文件中。
#: No.1 model starts
#: (‘SFRC: The final count of fibers:’, 47)
#: (‘SFRC: The final Vf:’, 0.0996670269351362)
#: CFRC: Unable to find a suitable position for new fiber after 1000 attempts.
#: (‘CFRC: The final count of fibers:’, 103)
#: (‘CFRC: The final Vf:’, 0.33093822612247)
#: CFRC: Unable to find a suitable position for new fiber after 1000 attempts.
#: (‘CFRC: The final count of fibers:’, 103)
#: (‘CFRC: The final Vf:’, 0.33093822612247)
#: E11=109.446835937 Stress units
#: V12=0.351698970795 ratio
txt文件中,存在以上面例子为例的很多组数据,现在想要从每组数据中获取SFRCVf CFRCVf CFRCVf E11 V12后面的数值,从而形成多行多列的array数组
#: No.2 model starts
#: (‘SFRC: The final count of fibers:’, 47)
#: (‘SFRC: The final Vf:’, 0.0996670269351362)
#: CFRC: Unable to find a suitable position for new fiber after 1000 attempts.
#: (‘CFRC: The final count of fibers:’, 103)
#: (‘CFRC: The final Vf:’, 0.33093822612247)
#: CFRC: Unable to find a suitable position for new fiber after 1000 attempts.
#: (‘CFRC: The final count of fibers:’, 103)
#: (‘CFRC: The final Vf:’, 0.33093822612247)
#: retry No.2 model
#: (‘SFRC: The final count of fibers:’, 47)
#: (‘SFRC: The final Vf:’, 0.0996670269351362)
#: CFRC: Unable to find a suitable position for new fiber after 1000 attempts.
#: (‘CFRC: The final count of fibers:’, 103)
#: (‘CFRC: The final Vf:’, 0.33093822612247)
#: CFRC: Unable to find a suitable position for new fiber after 1000 attempts.
#: (‘CFRC: The final count of fibers:’, 103)
#: (‘CFRC: The final Vf:’, 0.33093822612247)
#: E11=109.446835937 Stress units
#: V12=0.351698970795 ratio
最佳方案
# 定义一个函数,lines中包含了一组数据中的所有行,针对这些行进行一组数据的提取
def extract_values(lines):
sfrc_vf = None
cfrc_vf_list = [] # 因为CFRC出现了两次,还是同名,因此用数组提取
e11 = None
v12 = None
for line in lines:
if '#: (\'SFRC: The final Vf:\', ' in line:
line = line.split('#: (\'SFRC: The final Vf:\', ')
sfrc_vf = line[1][:-2]
elif '#: (\'CFRC: The final Vf:\', ' in line:
line = line.split('#: (\'CFRC: The final Vf:\', ')
cfrc_vf_list.append(line[1][:-2])
elif '#: E11' in line:
line = line.split('#: E11=')
line = line[1].split(' Stress units')
e11 = line[0][:-1]
if '#: V12' in line:
line = line.split('#: V12=')
line = line[1].split(' ratio')
v12 = line[0][:-1]
cfrc_vf = (float(cfrc_vf_list[0])+float(cfrc_vf_list[1]))/2
return sfrc_vf, cfrc_vf, e11, v12
# 读取文本文件内容
with open('abaqus.rpy', 'r') as file:
lines = file.readlines()
# 构建数组
results = [] # 包含所有组的结果
current_data = [] # 一组数据的所有行
for line in lines:
# 实际上第一次#: No.1时current_data为空,因此没什么动作,仅仅每次都添加line
# 第二次,遇到#: No.2时current_data包含了第一组的全部行,因此results.append
# 完成一组数据后,current_data清零重新计数
if line.startswith("#: No.") or "retry No." in line:
if current_data:
results.append(extract_values(current_data))
current_data = []
current_data.append(line)
# 处理最后一组数据:由于以上代码漏了最后一组,因此补上
if current_data:
results.append(extract_values(current_data))
# 将结果转换为数组
result_array = np.array(results)
output_file = 'output.csv'
header = ['SFRC_Vf', 'CFRC_Vf', 'E11', 'v12']
with open(output_file, 'w', newline='') as csvfile:
csv_writer = csv.writer(csvfile)
# 写入头部
csv_writer.writerow(header)
# 写入数据
for row in result_array:
csv_writer.writerow(row)
废弃的方案
txt文件预处理
rpy文件直接重命名为txt文件方便操作。
为简化代码操作,首先对txt文件进行简单的处理。
原rpy文件如下图所示,在图中最后两行才是需要的数据,由于批量执行的规律性,发现从第一次有效数据开始,每隔47行为下组数据。
因此,删除第一组数据之前的无效代码。观察到,数据后包含“ Stress units”与“ ratio”无效后缀,因此可用文件中“替代”操作删除该后缀。得到新txt文件如图所示。
python代码
代码与注释如下
import numpy as np
import csv
# 使用list存放数据
list = []
# 使用with open可以不用繁琐地使用close()
# 先进行txt文件数据的读取
with open('test out.txt', 'r') as f:
# enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据下标和数据
# row_num为当前行数,line为当前行数据
for row_num, line in enumerate(f):
# 第1行与之后的i+47行包含E11数据
if row_num % 47 == 0:
# 可使用split函数进行数据提取,根据上图,数据包含在line[1]中
line = line.split('#: E11=')
# 由于该方法提取数据后,line[1]最后有字符'/n',所以使用[:-1],保留除了最后的字符的数据。添加至list中
list.append(line[1][:-1])
# 这里V12直接添加到E11后面了
if row_num % 47 == 1:
line = line.split('#: V12=')
list.append(line[1][:-1])
# 为了写入csv时为两列,使用array的reshape功能,将list变为两列的arr
arr = np.array(list).reshape(-1, 2)
# newline=''可避免写入csv后出现空白行
with open("test.csv", "w", newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerows(arr)
打赏博主
制作不易,如果有能帮到你,可以打赏博主一瓶可乐