我有一个看起来像这样的数据文件:

FBpp0070000 acyr193594273 acyr 866
FBpp0070000 acyr193577824 acyr 536
FBpp0070000 acyr193693009 acyr 445
FBpp0070000 bomb193605819 bomb 503
FBpp0070000 bomb193676398 bomb 101
FBpp0070001 acyr193618043 acyr 316
FBpp0070001 acyr193617997 acyr 313
FBpp0070001 bomb193638865 bomb 482
FBpp0070001 locu193695159 locu 220
FBpp0070001 locu193638863 locu 220

数据文件长约45,000行。

我的目标是拥有:

FBpp0070000 acyr193594273 acyr 866
FBpp0070000 bomb193605819 bomb 503
FBpp0070001 acyr193618043 acyr 316
FBpp0070001 bomb193638865 bomb 482
FBpp0070001 locu193695159 locu 220

也就是说,对于第3列中的每个不同值,对于第1列中的每个值,仅保留第4列中最高分的这些行。

另外,我看到的问题是1)第1和2列中的多重,重复的“键”,第4列中的“得分”相等;我只想保留一个重复的“得分”实例。

过去,我在Perl中构建了一个可以处理多个重复键的哈希。

到目前为止,这是我在Ruby中拥有的东西。

hash = Hash.new{|h,k| h[k]=Hash.new(&h.default_proc) }  
title = ''

File.open('test1.txt', 'r').each do |line|
  line.chomp!

     query, hit, taxa, score = line.split(/\s/)
     hash[query][hit][taxa] = score

 # end

#p "#{query}: #{taxa}: #{score}"

end
p hash

因此,我希望有人可以帮助我确定1)如果我确实正确地进行了此操作,以及2)如果是,则如何提取我需要的线。

谢谢。

有帮助吗?

解决方案

鉴于您在上面给出的输入示例,以下内容似乎可以按照您的意愿进行操作。您需要在末尾求解数据以获取所需的输出格式。

#!/usr/bin/env ruby

require 'pp'

data = {}
File.open("input.txt", "r").each do |l| 
  l.chomp!
  query, hit, taxa, score = l.split(/\s+/)
  data[query] ||= {}
  data[query][taxa] ||= [0, nil]
  data[query][taxa] = [score.to_i, hit] if score.to_i > data[query][taxa].first
end 

pp data

这给出了:

dj2@Magnus:~/Development/test $ ./out.rb 
{"FBpp0070000"=>
  {"bomb"=>[503, "bomb193605819"], "acyr"=>[866, "acyr193594273"]},
 "FBpp0070001"=>
  {"bomb"=>[482, "bomb193638865"],
   "locu"=>[220, "locu193695159"],
   "acyr"=>[316, "acyr193618043"]}}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top