2017-03-06 92 views
0

我有固定字段格式的字母数字数据的文本文件,但格式因行而异,所以我无法做到一个固定的字段读取。 我正在逐行阅读,识别记录类型,并根据该记录类型的格式进行切片。这里有一个$ Comments和三条数据记录分成两行的例子。 (顺便说一句,由于这是一种可以追溯到旧的“IBM打卡”或“Hollerith”卡的格式,这些卡被限制在80列,而最后的8列保留用于序列号以防万一你把你的卡,你把它们放在一个卡片分类机:-)如何转换为浮点数字的字符串表示形式,没有“e”

MOMENT* 3    15    0    1.00297+9 
*  .123092   -.984732  -.123092 
$ Nodal Forces of Load Set : Force 
FORCE* 1    15    0    1.00297+9 
*  .123092   -.984732  -.123092 
MOMENT* 3    15    0    1.00297+9 
*  .123092   -.984732  -.123092 

这里就是我遇到麻烦: 的Python似乎有麻烦的转换格式指数。 第二的最后一个字段考虑到最后一行:

In [50]: Card1 
Out[50]: 'MOMENT* 3    15    0    1.00297+9' 

切片,去年我场得到:

Card1[54:] 
Out[49]: ' 1.00297+9' 

如果我再剥去白色空间和字符串转换为浮动,我得到一个“float()”的无效文字。

float(str.strip(Card1[54:])) 
Traceback (most recent call last): 

    File "<ipython-input-52-64ddef289a29>", line 1, in <module> 
    float(str.strip(Card1[54:])) 

ValueError: invalid literal for float(): 1.00297+9 

显然,我们知道如何解释“1.00297 + 9”,但是Python似乎需要一个“E”或“E”认识到这是科学记数法:

float(str.strip(Card1[54:]).replace("+","E")) 
Out[53]: 1002970000.0 

我的问题在于负数的负指数。很显然,通过将“-123.45-3”转换为“E123.45E3”,replace()会打破负指数的负数。

理想情况下,会有一些简单的方法告诉Python仅使用+或 - 在数字的末尾来识别指数。

我唯一能想到的就是将字符串拼接成部分,如下所示。虽然这有效,但它不是优雅的...必须有更好的方法。

In[56]: String="-1.6486-5" 
In[57]: float(String[0:1]+String[1:].replace("-","E-")) 
Out[57]: -1.6486e-05 
+0

为什么将非标准浮点文字转换为float()能够解析的文字并不优雅?有时候恼人的技术问题需要烦人的解决方案。你看起来很好。 –

+0

是的,“讨厌”是一个正确的表达!我没有意识到,省略“E”是非标准的。我已经看到这么长时间了,它对我来说只是“正常”,但我会接受它是非标准的。在这种情况下,我的解决方案可能会达到它的效果。 谢谢! 我在1977年学习了FORTRAN,我对Python的优雅印象非常深刻。我对Python相当陌生,并且确信自己必须有更好的方式......也许不是。 –

+0

在Python中,通常*是一种更优雅的方式,但这种特殊情况似乎很难处理。正则表达式是原则性的方式,但在这种情况下是边界矫枉过正。 –

回答

1

我建议使用一个正则表达式替换 https://docs.python.org/2/library/re.html#re.sub 和匹配作为EITHER +/- 例如(开始)(0+位数)(正好为1位)(+或 - )(1个+位数) 或试图2个替换一前一后用+和 - 分别

0

鉴于这是非标准符号对于指数,我不希望任何事情比我想出了更好的:(更改替换了“e”,因为这就是Python的回报。)

In[56]: String="-1.6486-5" 
In[57]: float(String[0:1]+String[1:].replace("-","e-")) 
Out[57]: -1.6486e-05 

感谢所有谁评论!

相关问题