python:杂乱内容中提取数据:abaqus二次开发rpy文件数据提取

问题描述

适用问题:在文本文档中,存在多组数据,每组数据以不固定的行数出现,但是每组包含信息的形式存在重复性;需要将每组数据提取出来。

使用脚本控制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)

打赏博主

制作不易,如果有能帮到你,可以打赏博主一瓶可乐
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值