1

我得到了两个文件,每个文件都包含一个带有“时间”的列和一个带有“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

4 回答 4

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)}

我已经忘记了所有关于 dict 的理解。

于 2012-07-20T12:03:04.230 回答
2

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

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

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

于 2012-07-20T10:42:16.657 回答
0

This is a bit old school. Look at using a default dict from the collections module for a more elegant approach.

This will work for any number of files, I've named mine f1, f2 etc. The general idea is to process each file and build up a list of time values for each id. After file processing, iterate over the dictionary subtracting each value as you go (via reduce on the values list).

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}

Updated

If you want to include only those ids with more than one value:

results = {}
for k,v in d.items():
    if len(v) > 1:
        results[k] = reduce(sub, v)
于 2012-07-20T10:55:14.363 回答
0

You can use this as a base (instead of treating '11.24' as a float, I guess you want to adapt for hours/minutes or minutes/seconds)... you can effectively union and subtract matching keys using a defaultdict.

As long as you can get your data into a format like this:

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]
]

Then:

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

Results in:

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

For matches only

matches = dict( (k, v) for v, k in f1 )
d2 = dict( (k, v) for v, k in f2 )

for k, v in matches.items():
    try:
        matches[k] = v - d2[k]
    except KeyError as e:
        del matches[k]

print matches
# {1: -0.009999999999999787, 3: 0.009999999999999787, 6: -0.009999999999999787}
于 2012-07-20T10:57:04.877 回答