Vă mulțumim pentru susținere

Maparea valorilor din două matrice în Ruby

Mă întreb dacă există o modalitate de a face ce pot face mai jos cu Python, în Ruby:

sum = reduce(lambda x, y: x + y, map(lambda x, y: x * y, weights, data))

Am două matrici de dimensiuni egale cu greutățile și datele, dar nu pot să găsesc o funcție similară hărții în Ruby, să reduc am lucrat.

0
adăugat editat

6 răspunsuri

În Ruby 1.9:

weights.zip(data).map{|a,b| a*b}.reduce(:+)

În Ruby 1.8:

weights.zip(data).inject(0) {|sum,(w,d)| sum + w*d }
0
adăugat
weights = [1,2,3]
data    = [10,50,30]

require 'matrix'
Vector[*weights].inner_product Vector[*data] # => 200 
0
adăugat

@Michiel de Mare

Exemplul Ruby 1.9 poate fi scurtat un pic mai departe:

weights.zip(data).map(:*).reduce(:+)

De asemenea, rețineți că în Ruby 1.8, dacă aveți nevoie de ActiveSupport (de la Rails), puteți utiliza:

weights.zip(data).map(&:*).reduce(&:+)
0
adăugat
@FelixRabe: Se pare că rubinia a schimbat modul în care argumentele sunt tratate în acest tip de proc. Nu prea știu detalii, pentru că nu am atins rubinii în câțiva ani.
adăugat autor Kevin Ballard
Aceasta nu funcționează pentru mine pe Ruby 1.9.3 (ArgumentError): [1,2,3] .zip ([4,5,6]) harta (: *)
adăugat autor Felix Rabe

Ruby are o metodă map (metoda collect ), care poate fi aplicată oricărui obiect Enumerable . Dacă numbers este o serie de numere, următoarea linie în Ruby:

numbers.map{|x| x + 5}

este echivalentul liniei următoare în Python:

map(lambda x: x + 5, numbers)

Pentru mai multe detalii, consultați aici sau aici .

0
adăugat

Funcția Array.zip face o combinație elementală de matrice. Nu este la fel de curată ca sintaxa Python, dar iată o abordare pe care o puteți folosi:

weights = [1, 2, 3]
data = [4, 5, 6]
result = Array.new
a.zip(b) { |x, y| result << x * y } # For just the one operation

sum = 0
a.zip(b) { |x, y| sum += x * y } # For both operations
0
adăugat

O alternativă pentru hartă care funcționează și pentru mai mult de 2 mese:

def dot(*arrays)
  arrays.transpose.map {|vals| yield vals}
end

dot(weights,data) {|a,b| a*b} 

# OR, if you have a third array

dot(weights,data,offsets) {|a,b,c| (a*b)+c}

Acest lucru ar putea fi adăugat și în Array:

class Array
  def dot
    self.transpose.map{|vals| yield vals}
  end
end

[weights,data].dot {|a,b| a*b}

#OR

[weights,data,offsets].dot {|a,b,c| (a*b)+c}
0
adăugat