我有两个文件,每个文件包含一个带有“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,但现在我被卡住了。非常感谢任何帮助,谢谢。
答案 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来获得更优雅的方法。
这适用于任意数量的文件,我将其命名为我的f1
,f2
等。一般的想法是处理每个文件并为每个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}