在python中减去匹配的行

时间:2012-07-20 10:35:01

标签: python

我有两个文件,每个文件包含一个带有“time”的列和一个带有“id”的列,如下所示:

文件1:

time     id
11.24    1
11.26    2
11.27    3
11.29    5
11.30    6

文件2:

time     id
11.25    1
11.26    3
11.27    4
11.31    6
11.32    7
11.33    8

我试图做一个python脚本,它可以减去彼此匹配id的行的时间。文件长度不同。

我尝试使用set(id's of file 1) & set(id's of file 2)来获取匹配的ID,但现在我被卡住了。非常感谢任何帮助,谢谢。

4 个答案:

答案 0 :(得分:3)

列表推导可以很容易地解决问题:

#read these from file if you want to, included in this form for brevity
F1 = {1: 11.24, 2: 11.26, 3:11.27, 5:11.29, 6:11.30}
F2 = {1:11.25, 3:11.26, 4:11.27, 6:11.31, 7:11.32, 8:11.33}

K1 = set(F1.keys())
K2 = set(F2.keys())

result = dict([ (k, F1[k] - F2[k]) for k in (K1 & K2)])
print result

这将输出:

{1: -0.009999999999999787, 3: 0.009999999999999787, 6: -0.009999999999999787}

编辑:正如mhawke指出的那样,最后一行可以是:

result = {k: F1[k] - F2[k]) for k in (K1 & K2)}

我忘记了关于字典理解的一切。

答案 1 :(得分:2)

Python Set不支持元素的排序。我会将数据存储为字典

file1 = {1:'11:24', 2:'11:26', ... etc}
file2 = {1:'11:25', 3:'11:26', ... etc}

在键的交叉点上循环(或根据您的需要使用联合)来进行减法(基于时间或基于数学)。

答案 2 :(得分:0)

这是一所古老的学校。请使用collections模块中的默认dict来获得更优雅的方法。

这适用于任意数量的文件,我将其命名为我的f1f2等。一般的想法是处理每个文件并为每个id建立一个时间值列表。在文件处理之后,迭代字典,在你去的时候减去每个值(通过值列表上的reduce)。

from operator import sub

d = {}
for fname in ('f1','f2'):
    for l in open(fname):
        t, i = l.split()
        d[i] = d.get(i, []) + [float(t)]

results = {}
for k,v in d.items():
    results[k] = reduce(sub, v)

print results
{'1': -0.009999999999999787, '3': 0.009999999999999787, '2': 11.26, '5': 11.29, '4': 11.27, '7': 11.32, '6': -0.009999999999999787, '8': 11.33}

<强>更新

如果您只想包含具有多个值的ID:

results = {}
for k,v in d.items():
    if len(v) > 1:
        results[k] = reduce(sub, v)

答案 3 :(得分:0)

您可以将此作为基础使用(而不是将'11 .24'视为浮点数,我猜您想要适应小时/分钟或分钟/秒)...您可以使用{有效地合并和减去匹配的键{1}}。

只要您可以将数据转换为以下格式:

defaultdict

然后:

f1 = [
    [11.24, 1],
    [11.26, 2],
    [11.27, 3],
    [11.29, 5],
    [11.30, 6]
]

f2 = [
    [11.25, 1],
    [11.26, 3],
    [11.27, 4],
    [11.31, 6],
    [11.32, 7],
    [11.33, 8]
]

结果:

from collections import defaultdict
from itertools import chain

dd = defaultdict(float)
for k, v in chain(
    ((b, a) for a, b in f1),
    ((b, -a) for a, b in f2)): # negate a

    dd[k] += v

仅限比赛

{1: -0.009999999999999787,
 2: 11.26,
 3: 0.009999999999999787,
 4: -11.27,
 5: 11.29,
 6: -0.009999999999999787,
 7: -11.32,
 8: -11.33}