如何在Python中从文件提取浮点数?
我有一个文件,内容大概是这样的:
# 3e98.mtz MR_AUTO with model 200la_.pdb
SPACegroup HALL P 2yb #P 1 21 1
SOLU SET RFZ=3.0 TFZ=4.7 PAK=0 LLG=30
SOLU 6DIM ENSE 200la_ EULER 321.997 124.066 234.744 FRAC -0.14681 0.50245 -0.05722
SOLU SET RFZ=3.3 TFZ=4.2 PAK=0 LLG=30
SOLU 6DIM ENSE 200la_ EULER 329.492 34.325 209.775 FRAC 0.70297 0.00106 -0.24023
SOLU SET RFZ=3.6 TFZ=3.6 PAK=0 LLG=30
SOLU 6DIM ENSE 200la_ EULER 177.344 78.287 187.356 FRAC 0.04890 0.00090 -0.57497
我想知道,最好的方法是什么,来遍历这个文件并提取出所有的浮点数?
在这个情况下,最理想的情况是提取出像“321.997”这样的数字(这些是病毒细胞结构的坐标),然后把它们放到一个列表里。在我查看的每个文件中,每一行都有6个这样的数字。提取出这些数字后,我可以用这个列表在我已经写好的方法中计算新的坐标,以便把细胞结构旋转到与数据集中其他结构匹配。
4 个回答
在编程中,有时候我们会遇到一些问题,特别是在使用某些工具或库的时候。比如说,当你在写代码时,可能会发现某个功能没有按照预期工作。这时候,很多人会去网上查找解决方案,比如在StackOverflow上提问或搜索。
StackOverflow是一个程序员交流的平台,大家可以在这里分享自己的问题和解决办法。你可以看到很多人遇到过类似的问题,并且他们会把自己的解决方案写出来,帮助其他人。
在提问时,最好能把你的代码、错误信息和你尝试过的解决办法都写上,这样别人才能更好地理解你的问题,给出有效的建议。
总之,遇到问题时,不要害怕寻求帮助,社区里有很多热心的人愿意提供支持。
floats = []
all = ['#', '3e98.mtz', 'MR_AUTO', 'with', 'model', '200la_.pdb', 'SPACegroup', 'HALL', 'P', '2yb', '#P', '1', '21', '1', 'SOLU', 'SET', 'RFZ=3.0', 'TFZ=4.7', 'PAK=0', 'LLG=30', 'SOLU', '6DIM', 'ENSE', '200la_', 'EULER', '321.997', '124.066', '234.744', 'FRAC', '-0.14681', '0.50245', '-0.05722', 'SOLU', 'SET', 'RFZ=3.3', 'TFZ=4.2', 'PAK=0', 'LLG=30', 'SOLU', '6DIM', 'ENSE', '200la_', 'EULER', '329.492', '34.325', '209.775', 'FRAC', '0.70297', '0.00106', '-0.24023', 'SOLU', 'SET', 'RFZ=3.6', 'TFZ=3.6', 'PAK=0', 'LLG=30', 'SOLU', '6DIM', 'ENSE', '200la_', 'EULER', '177.344', '78.287', '187.356', 'FRAC', '0.04890', '0.00090', '-0.57497']
for element in all:
try:
floats.append(float(element))
except ValueError:
pass
这是一种方法。
def floats( aList ):
for v in aList:
try:
yield float(v)
except ValueError:
pass
a = list( floats( [....] ) )
如果你以一种让人不想仔细看结构的方式展示你的输入,然后问一些像“我怎么提取出所有的浮点数”这样的问题,同时把有用的信息,比如“我查看的每个文件每行都有6个这样的数字”,藏在评论里,那么你得到的回答可能就是你所要求的:一个包含3个多余数字(1.0, 21.0, 和 1.0)的“浮点数”列表。
如果你稍微友好一点地展示你的数据,比如:
alist = [
'#', '3e98.mtz', 'MR_AUTO', 'with', 'model', '200la_.pdb', 'SPACegroup', 'HALL', 'P', '2yb',
'#P', '1', '21', '1',
'SOLU', 'SET', 'RFZ=3.0', 'TFZ=4.7', 'PAK=0', 'LLG=30', 'SOLU', '6DIM', 'ENSE', '200la_',
'EULER', '321.997', '124.066', '234.744', 'FRAC', '-0.14681', '0.50245', '-0.05722',
'SOLU', 'SET', 'RFZ=3.3', 'TFZ=4.2', 'PAK=0', 'LLG=30', 'SOLU', '6DIM', 'ENSE', '200la_',
'EULER', '329.492', '34.325', '209.775', 'FRAC', '0.70297', '0.00106', '-0.24023',
'SOLU', 'SET', 'RFZ=3.6', 'TFZ=3.6', 'PAK=0', 'LLG=30', 'SOLU', '6DIM', 'ENSE', '200la_',
'EULER', '177.344', '78.287', '187.356', 'FRAC', '0.04890', '0.00090', '-0.57497'
]
那么人们就有可能注意到结构(EULER后面跟着三个数字,然后是FRAC后面也跟着三个数字)重复出现,可能会想“哦,他的文件每行有六个数字”,然后给你一些更有用的建议,比如:
从头开始,告诉我们你的文件结构是什么。可能有更好的方法来获取你的信息,而不是把文件拆成字符串列表,然后再试图从中恢复。
更新 现在,这里有一个利用你数据和评论中明显结构的答案,如果结构有变化,这样的代码会更容易调试:
TAG0 = 'EULER'
TAG1 = 'FRAC'
def extract_rows(tokens):
pos = 0
while True:
try:
pos = tokens.index(TAG0, pos)
except ValueError:
return
assert pos + 8 <= len(tokens)
assert tokens[pos+4] == TAG1
yield (
tuple(map(float, tokens[pos+1:pos+4])),
tuple(map(float, tokens[pos+5:pos+8])),
)
pos += 8
for rowx, row in enumerate (extract_rows(alist)):
print rowx, 'TAG0', row[0]
print rowx, 'TAG1', row[1]
结果:
0 TAG0 (321.99700000000001, 124.066, 234.744)
0 TAG1 (-0.14681, 0.50244999999999995, -0.05722)
1 TAG0 (329.49200000000002, 34.325000000000003, 209.77500000000001)
1 TAG1 (0.70296999999999998, 0.00106, -0.24023)
2 TAG0 (177.34399999999999, 78.287000000000006, 187.35599999999999)
2 TAG1 (0.048899999999999999, 0.00089999999999999998, -0.57496999999999998)
更新2 根据你的示例文件,以下简单代码(未经测试)应该能满足你的需求:
for line in open('my_file.txt'):
row = line.split()
if row[0] == 'SOLU' and row[1] == '6DIM' and row[4] == 'EULER' and row[8] == 'FRAC':
euler = map(float, row[5:8])
frac = map(float, row[9:12])
do_something_with(euler, frac)
注意:你所寻找的“所有浮点数”只是巧合(这还忽略了RFZ=3.0 TFZ=4.7
中的浮点数!)。你实际上有一个有结构的文件:两种类型的SOLU记录,你想要的是在SOLU 6DIM记录中EULER后面出现的3个数字和FRAC后面出现的3个数字。你并不想要所有这些数字的列表,然后再把它们分成(3个EULER数字和3个FRAC数字)乘以N。