从非二次表中读取数组
Posted
技术标签:
【中文标题】从非二次表中读取数组【英文标题】:Read an array from a non-quadratic table 【发布时间】:2017-10-11 09:51:57 【问题描述】:我在读取如下所示的表格时遇到问题:
$TITLE = 1
$SUBTITLE= 2
$LABEL = SUBCASE - STATIC LOADS 1 3
$DISPLACEMENTS 4
$REAL OUTPUT 5
$SUBCASE ID = 1 6
1 G 1.100698E-02 1.961111E-03 -1.888102E-01 7
-CONT- 0.000000E+00 0.000000E+00 0.000000E+00 8
2 G 1.099767E-02 1.947526E-03 -1.814562E-01 9
-CONT- 0.000000E+00 0.000000E+00 0.000000E+00 10
3 G 1.097209E-02 1.915010E-03 -1.741153E-01 11
-CONT- 0.000000E+00 0.000000E+00 0.000000E+00 12
4 G 1.093050E-02 1.873149E-03 -1.667979E-01 13
-CONT- 0.000000E+00 0.000000E+00 0.000000E+00 14
5 G 1.087178E-02 1.827145E-03 -1.595153E-01 15
-CONT- 0.000000E+00 0.000000E+00 0.000000E+00 16
我想要的是这样的:
1.100698E-02 1.961111E-03 -1.888102E-01 0.000000E+00 0.000000E+00 0.000000E+00
1.099767E-02 1.947526E-03 -1.814562E-01 0.000000E+00 0.000000E+00 0.000000E+00
1.097209E-02 1.915010E-03 -1.741153E-01 0.000000E+00 0.000000E+00 0.000000E+00
1.093050E-02 1.873149E-03 -1.667979E-01 0.000000E+00 0.000000E+00 0.000000E+00
1.087178E-02 1.827145E-03 -1.595153E-01 0.000000E+00 0.000000E+00 0.000000E+00
所以我尝试了几件事,但总是遇到一些问题。
首先我尝试通过 numpy.loadtxt 加载数据并省略标题行。但是我在获取正确的数据类型时遇到了问题。当我用 dtype=string 读入它时,我无法将它正确转换为再次浮动。
PunchData = loadtxt(PunchFile, skiprows=6)
ValueError:无法将字符串转换为浮点数:G
之后我尝试使用 genfromtxt 填充所有空列,以便他可以将其读取为二次数组。但我无法让它工作,因为列数不匹配 -> number 并且 G 产生 2 列,而 -cont- 产生 1 列。
kwargs = dict(dtype=float, 跳过标题=6, 缺失值=0:" ", 1:" ", 2:" ", 3:" ", 4:" ", 5:" ", 填充值=0:0, 1:0, 2:0, 3:0, 4:0, 5:0) PunchData = genfromtxt(PunchFile, **kwargs)
ValueError:检测到一些错误! 第 8 行(有 5 列而不是 6 列) 第 10 行(有 5 列而不是 6 列) 第 12 行(得到 5 列而不是 6 列) 第 14 行(有 5 列而不是 6 列) 第 16 行(得到 5 列而不是 6 列)
作为最后一种方法,我尝试使用 readlines 读取数据,但这会导致与第一种方法相同的问题。我得到了一些字符串,但无法将其转换为 numpy 数组。
f = 打开(PunchFile) 行=f.readlines() 行=行[6:] 数据=[] 换行: data.append(line[24:])
['1.100698E-02 1.961111E-03 -1.888102E-01 7\n', '0.000000E+00 0.000000E+00 0.000000E+00 8\n', '1.099767E-02 1.947526E-03 -1.814562E-01 9\n', '0.000000E+00 0.000000E+00 0.000000E+00 10\n', '1.097209E-02 1.915010E-03 -1.741153E-01 11\n', '0.000000E+00 0.000000E+00 0.000000E+00 12\n', '1.093050E-02 1.873149E-03 -1.667979E-01 13\n', '0.000000E+00 0.000000E+00 0.000000E+00 14\n', '1.087178E-02 1.827145E-03 -1.595153E-01 15\n', '0.000000E+00 0.000000E+00 0.000000E+00 16']
所以我真的很挣扎,不知道该怎么做。你们能帮我吗?
【问题讨论】:
【参考方案1】:只需手动处理。您的行包含固定大小的字段,后缀是行号,前缀可以是:
评论指示符 ($) 续行指示符 (-CONT-) 一个行号和一个你忽略的 G所以你必须:
跳过以$
开头的行
每行只保留 72 个首字符
将以-CONT-
开头的行连接到前一行,但要从中跳过 18 个字符
从不以-CONT-
开头的行中跳过 24 个字符
它产生以下代码:
PuchData = []
with open(PunchFile) as fd:
old = None
for line in fd:
if line.startswith('$'): continue
line = line[:72]
if line.startswith('-CONT-'):
old += line[18:]
else:
if old is not None: PuchData.append(old.split())
old = line[24:]
data.append(old.split())
【讨论】:
刚刚尝试了这个解决方案,它工作得很好,但它需要很长时间,即使对于这 5 行也是如此。有没有办法做到时间优化? 持续这么久很奇怪,因为没有涉及到真正复杂的操作。您能否提供更多详细信息(平台、行数、经过时间) 好的,看起来根本不需要很长时间。只用了 0.0160000324249 秒。所以可能是Shell,启动脚本需要很长时间。以上是关于从非二次表中读取数组的主要内容,如果未能解决你的问题,请参考以下文章