بناء تجزئة من التجزئة لتحديد أكبر قيمة عددية في روبي

StackOverflow https://stackoverflow.com/questions/4207026

  •  25-09-2019
  •  | 
  •  

سؤال

لدي ملف بيانات يشبه هذا:

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

يبلغ طول ملف البيانات ~ 45000 خط.

هدفي هو الحصول على هذا:

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

وهذا يعني ، احتفظ فقط بتلك الخطوط بأعلى درجة في العمود 4 ، لكل قيمة مختلفة في العمود 3 ، لكل قيمة في العمود 1.

بالإضافة إلى ذلك ، فإن المشكلات التي أراها هي 1) "مفاتيح" متعددة ، مكررة في العمود 1 و 2) متساوية "الدرجات" في العمود 4 ؛ أريد فقط الاحتفاظ بمثيل واحد فقط "النتيجة" المكررة.

لقد قمت ، في الماضي ، ببناء تجزئة في Perl والتي يمكنها التعامل مع مفاتيح مكررة متعددة.

هذا ما لدي في روبي حتى الآن.

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