2008-08-06 17 views
18

me pregunto si hay una manera de hacer lo que puedo hacer a continuación con Python, en Ruby:Asignación de valores de matriz de dos en Ruby

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

que tienen dos matrices de igual tamaño con los pesos y los datos pero parece que no puedo encontrar una función similar a la del mapa en Ruby, reduzco el trabajo.

Respuesta

13

@Michiel de Mare

Su ejemplo Ruby 1.9 se puede acortar un poco más lejos:

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

También tenga en cuenta que en Rubí 1,8, si necesita ActiveSupport (de Rieles), puede utilizar:

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

que no funciona para mí sobre el Ruby 1.9.3 (ArgumentError.): '[1,2,3] .zip ([4,5,6]) mapa (: *) ' –

+0

@Fe lixRabe: Parece que ruby ​​ha cambiado la forma en que se manejan los argumentos en este tipo de proceso. Realmente no conozco ningún detalle, ya que no he tocado el rubí en algunos años. –

1

La función Array.zip realiza una combinación de matrices con elementos. No es tan limpio como la sintaxis de Python, pero aquí es uno de los enfoques que podría utilizar:

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 
1

Ruby tiene un método map (también conocido como el método collect), que se puede aplicar a cualquier objeto Enumerable. Si numbers es una matriz de números, la línea siguiente en Ruby:

numbers.map{|x| x + 5} 

es el equivalente de la línea siguiente en Python:

map(lambda x: x + 5, numbers) 

Para más detalles, ver here o here.

5

En Ruby 1.9:

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

en Ruby 1.8:

weights.zip(data).inject(0) {|sum,(w,d)| sum + w*d } 
0

Una alternativa para el mapa que funciona desde hace más de 2 matrices, así:

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} 

Esto también podría añadirse a matriz:

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
weights = [1,2,3] 
data = [10,50,30] 

require 'matrix' 
Vector[*weights].inner_product Vector[*data] # => 200 
Cuestiones relacionadas