0

我在这样的列中的文件中有一个浮点数列表:

123.456

234.567

345.678

我如何生成一个输出文件,该文件是通过将一行中的值减去其上方的值而生成的。对于上面的输入文件,生成的输出应该是:

123.456-123.456

234.567-123.456

345.678-234.567

第一个值应该返回零,但其他值应该减去它上面的值。这不是一个家庭作业问题。这是我更大问题的一个小要求,我被困在这一点上。非常感谢帮助。谢谢 !!

4

3 回答 3

2

这将起作用:

diffs = [0] + [j - data[i] for i,j in enumerate(data[1:])]

所以,假设data.txt包含:

123.456
234.567
345.678

然后

with open('data.txt') as f:
    data = f.readlines()
    diffs = [0] + [float(j) - float(data[i]) for i,j in enumerate(data[1:])]

print diffs

将产生

[0, 111.111, 111.11099999999999]

此答案假定您要保留计算值以供进一步处理。

如果您想在某个时候将这些内容写到文件中,请逐行:

with open('result.txt', 'w') as outf:
    for i in diffs:
        outf.write('{0:12.5f}\n'.format(i))

并调整字段宽度以满足您的需要(现在保留 12 个空格,小数点后 5 个),写入文件result.txt.

更新:鉴于(来自下面的评论)内存中可能有太多数据无法保存,这个解决方案应该可以工作。Python 2.6 不允许在同一个文件中打开两个文件with,因此需要单独的语句。

with open('result2.txt', 'w') as outf:
    outf.write('{0:12.5f}\n'.format(0.0))
    prev_item = 0;
    with open('data.txt') as inf:
        for i, item in enumerate(inf):
            item = float(item.strip())
            val = item - prev_item
            if i > 0:
                outf.write('{0:12.5f}\n'.format(val))
            prev_item = item

有点hack的感觉。虽然不会在内存中创建一个巨大的列表。

于 2012-06-05T16:33:48.267 回答
2

给定一个值列表:

[values[i] - values[i-1] if i > 0 else 0.0 for i in range(len(values))]
于 2012-06-05T16:34:43.783 回答
2

为什么不编写自己的生成器,而不是列表推导式或生成器表达式,它可以具有任意复杂的逻辑,并且可以轻松地对庞大的数据集进行操作?

from itertools import imap

def differences(values):
    yield 0  # The initial 0 you wanted
    iterator = imap(float, values)
    last = iterator.next()
    for value in iterator:
        yield value - last
        last = value

with open('data.txt') as f:
    data = f.readlines()

with open('outfile.txt', 'w') as f:
    for value in differences(data):
        f.write('%s\n' % value)

如果data只保留几个值,则好处不一定那么明显(尽管代码本身的明确性可能会在明年你必须回来维护它时很好)。但是假设data是来自巨大(或无限!)来源的值流,并且您想处理其中的前一千个值:

diffs = differences(enormousdataset)
for count in xrange(1000):
    print diffs.next()

最后,这适用于不可索引的数据源。跟踪索引号以查找值的解决方案不能很好地处理生成器的输出。

于 2012-06-05T17:16:39.733 回答