Pergunta

Eu tenho um arquivo de dados que se parece com o seguinte:

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

O arquivo de dados tem ~ 45.000 linhas de comprimento.

Meu objetivo é ter isso:

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

Ou seja, mantenha apenas essas linhas com a pontuação mais alta na coluna 4, para cada valor diferente na coluna 3, para cada valor na coluna 1.

Além disso, os problemas que estou vendo são 1) múltiplas "teclas" duplicadas na coluna 1 e 2) pontuações iguais na coluna 4; Eu quero manter apenas uma instância dessa "pontuação" duplicada.

No passado, eu construí um hash em Perl, que pode lidar com várias teclas duplicadas.

Aqui está o que tenho em Ruby até agora.

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

Então, espero que alguém possa me ajudar a determinar 1) se eu estiver, de fato, fazendo isso corretamente e 2) se sim, como extrair as linhas de que preciso.

Obrigado.

Foi útil?

Solução

A seguir, parece fazer o que você deseja, dado o exemplo de entrada que você deu acima. Você precisará recorrer a dados no final para obter o formato de saída desejado.

#!/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

Isto dá:

dj2@Magnus:~/Development/test $ ./out.rb 
{"FBpp0070000"=>
  {"bomb"=>[503, "bomb193605819"], "acyr"=>[866, "acyr193594273"]},
 "FBpp0070001"=>
  {"bomb"=>[482, "bomb193638865"],
   "locu"=>[220, "locu193695159"],
   "acyr"=>[316, "acyr193618043"]}}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top