【问题标题】:Python data manipulationPython 数据操作
【发布时间】:2014-03-31 19:38:14
【问题描述】:

我有两个文件作为输入。 (他们每个都有更多的列,但我只把它缩小到重要的列)

A   15.6            A   D
B   10.3            A   B
C   12.5            A   E
D   14.5            A   Y
E   11.4            C   A
F   23.7            C   B
                    C   R
                    D   A
                    D   R
                    D   F

第一个文件是一种索引。我想查看第二个文件并通过在第一个文件中查找它们的值并打印出具有较小值的键来比较这些对(如果其中一个键不在索引文件中 - 然后通过默认)。之后我想删除所有重复的条目,即

D   14.5
B   10.3
E   11.4                A   15.6
A   15.6                B   10.3
C   12.5    ------->    C   12.5
B   10.3                D   14.5
C   12.5                E   11.4
D   14.5
D   14.5
D   14.5

所以,它本质上是一个索引文件缩减。在 Python 中必须有一种优雅的方式来做到这一点......

【问题讨论】:

标签: python parsing sorting text reduction


【解决方案1】:
mapping = dict()
result = set()

with open(filename1, 'r') as f1, open(filename2, 'r') as f2:
    for line in f1:
        line = line.split()
        if line:
            key, val = line
            mapping[key] = float(val)  #1

    for line in f2:
        line = line.split()        
        if line:
            key1, key2 = line
            if key1 in mapping:   #4
                result.add(min(line, key=lambda x: mapping.get(x, float('inf'))))  #2

for key in result:
    print('{k} {v}'.format(k=key, v=mapping[key]))   #3
  1. 将第一个文件中的数据加载到字典中(称为mapping)。
  2. 收集与集合中最小值关联的所有键(称为result)。
  3. 报告密钥。请注意,由于resultset,因此没有 报告密钥的预定义顺序。
  4. 根据 cmets 中的额外要求,忽略 key1 所在的行 不在第一个文件中。

【讨论】:

  • 很棒的代码!谢谢!快速提问 - 如果 filename2 恰好是一个包含多列的大文件,我只想考虑 key1 与 filename2 中的任何一个键匹配的行 - 如何修改上面的代码? (在我的基本 bash 脚本中,我会为 filename1 中的每个键 grep 大文件名 2 ......这是非常低效的)。再次感谢!
  • 您可以使用if key1 in mapping。我已经编辑了上面的帖子以显示位置。
  • 我可能是通过看到有人使用它来了解这一点的,尽管我不记得是谁或在哪里。它起作用的原因是documented here:空元组的真值为False,否则为True。所以if line(在使用line = line.split()分割空白之后)是测试line是否有非空白内容的方法。
  • 再次感谢。你的代码激发了学习。我还没有在其他地方看到过构造 if line: ...在哪里可以详细了解它?
  • 好消息。很抱歉对上一条评论进行了奇怪的编辑...同时做 3 件事并且用完了 5 分钟的编辑限制...
【解决方案2】:

您可以按如下方式使用 zip:

with open("file1.txt","r") as file1,  open("file2.txt","r") as file2:
    for l1,l2 in zip(file1.readlines(), file2.readlines()):
        l1d=l1.split()
        l2d=l2.split()
        if l1d[0]==l2d[0]:
            if float(l1d[1]) < float(l2d[1]):
                print l1
            else:
                print l2
  1. 读取两个文件
  2. 使用 zip 迭代两个文件行
  3. 根据拆分结果查找最小值并显示最小保持字符串

【讨论】:

  • 对于新手(如我自己)来说效果很好,也更容易阅读和理解。不过,我给了 unutbu 解决方案复选标记……代码太紧凑了……只是研究它让我对 python 有了更深入的理解和感觉。谢谢。
【解决方案3】:

这可能是一种方式:

#1. Make a dictionary of the first file, so the look up is faster

a_dict = {}
for line in first_file:
    a, b = line.strip().split()
    a_dict[a] = b

#2. Get the second item in each line of second file and get 
#   its corresponding value from the dictionary we built.
#   op is another dict and will take care of getting rid of
#   duplicates.

op = defaultdit(list)
for line in second_file:
    a, b = line.split().strip()
    op[a].append(a_dict[b])

#3. Get the minimum value of all the candidates

res = {}
for k, v in op:
    res[k] = min(v)

print res

【讨论】:

    猜你喜欢
    • 2020-12-09
    • 2020-12-07
    • 1970-01-01
    • 2016-09-23
    • 2021-10-05
    • 2021-07-30
    • 2016-12-20
    • 2017-05-23
    • 1970-01-01
    相关资源
    最近更新 更多