【问题标题】:Python: How to extract floating point numbers from a text file with mixed content?Python:如何从具有混合内容的文本文件中提取浮点数?
【发布时间】:2012-06-19 02:26:02
【问题描述】:

我有一个制表符分隔的文本文件,其中包含以下数据:

    ahi1
    b/se
ahi 
test    -2.435953
        1.218364
    ahi2
    b/se
ahi 
test    -2.001858
        1.303935

我想将两个浮点数提取到一个包含两列的单独 csv 文件中,即。

-2.435953 1.218264

-2.001858 1.303935

目前我的黑客尝试是:

 import csv
 from itertools import islice
 results = csv.reader(open('test', 'r'), delimiter="\n")

 list(islice(results,3))
 print results.next()
 print results.next()
 list(islice(results,3))
 print results.next()
 print results.next()

这并不理想。我是 Python 的菜鸟,所以我提前道歉并感谢您的宝贵时间。

【问题讨论】:

  • 请注意,在您使用这些值的地方,一种稍微更有效的方法(避免构建列表)是执行next(islice(iterator, n, n), None) - 取自itertools docs 中的consume() 配方。

标签: python floating-point csv


【解决方案1】:

这是完成这项工作的代码:

import re

# this is the same data just copy/pasted from your question
data = """    ahi1
    b/se
ahi 
test    -2.435953
        1.218364
    ahi2
    b/se
ahi 
test    -2.001858
        1.303935"""

# what we're gonna do, is search through it line-by-line
# and parse out the numbers, using regular expressions

# what this basically does is, look for any number of characters
# that aren't digits or '-' [^-\d]  ^ means NOT
# then look for 0 or 1 dashes ('-') followed by one or more decimals
# and a dot and decimals again: [\-]{0,1}\d+\.\d+
# and then the same as first..
pattern = re.compile(r"[^-\d]*([\-]{0,1}\d+\.\d+)[^-\d]*")

results = []
for line in data.split("\n"):
    match = pattern.match(line)
    if match:
        results.append(match.groups()[0])

pairs = []
i = 0
end = len(results)
while i < end - 1:
    pairs.append((results[i], results[i+1]))
    i += 2

for p in pairs:
    print "%s, %s" % (p[0], p[1])

输出:

>>>
-2.435953, 1.218364
-2.001858, 1.303935

您可以将它们保存在一个列表中,然后将它们压缩在一起,而不是打印出来。 我正在使用python regular expression framework 来解析文本。如果您还不知道,我只能建议您选择正则表达式。我发现解析文本和各种机器生成的输出文件非常有用。

编辑:

哦,顺便说一句,如果您担心性能,我在我的慢速旧 2ghz IBM T60 笔记本电脑上进行了测试,我可以使用正则表达式在大约 200 毫秒内解析一兆字节。

更新: 我觉得很好,所以我为你做了最后一步:P

【讨论】:

  • 谢谢!了不起的努力,它可以像上面一样完美地工作,并且稍微修改一下它甚至可以与我的原始文件一起使用(我提到我是一个菜鸟,不是吗?)。我也会完全检查正则表达式的东西,谢谢你的建议。
  • 请注意,您可以使用列表理解来简化此操作。 matches = (pattern.match(line) for line in data.split("\n"))results = [match.group(0) for match in matches if match] 用于第一个列表构造。其次,您应该查看 itertools grouper() 配方。
  • 谢谢 Lattyware,我会试试的。我不确定我是否遵循了您上面的评论,但我也会尝试理解这一点。再次感谢。
【解决方案2】:

也许这会有所帮助

zip(*[results]*5)

例如

import csv
from itertools import izip
results = csv.reader(open('test', 'r'), delimiter="\t")
for result1, result2 in (x[3:5] for x in izip(*[results]*5)):
    ... # do something with the result

【讨论】:

  • 感谢您考虑我的问题并及时回答。我是 python 和编程的新手,所以不幸的是我还不能让它工作,但我会......最终!谢谢
【解决方案3】:

足够棘手但更有说服力和顺序的解决方案:

$ grep -v "ahi" myFileName | grep -v se | tr -d "test\" " | awk 'NR%2{printf $0", ";next;}1'
-2.435953, 1.218364
-2.001858, 1.303935

它是如何工作的:基本上删除特定的文本行,然后删除行中不需要的文本,然后每隔一行加入格式。我只是为了美化目的添加了逗号。如果不需要,请在 awks printf ", " 中留下逗号。

【讨论】:

    猜你喜欢
    • 2021-12-31
    • 1970-01-01
    • 2011-01-18
    • 2017-10-17
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 2016-09-09
    相关资源
    最近更新 更多