How can I do standard deviation in Ruby?

后端 未结 9 1457
一个人的身影
一个人的身影 2021-01-30 15:45

I have several records with a given attribute, and I want to find the standard deviation.

How do I do that?

9条回答
  •  执念已碎
    2021-01-30 16:34

    I'm not a big fan of adding methods to Enumerable since there could be unwanted side effects. It also gives methods really specific to an array of numbers to any class inheriting from Enumerable, which doesn't make sense in most cases.

    While this is fine for tests, scripts or small apps, it's risky for larger applications, so here's an alternative based on @tolitius' answer which was already perfect. This is more for reference than anything else:

    module MyApp::Maths
      def self.sum(a)
        a.inject(0){ |accum, i| accum + i }
      end
    
      def self.mean(a)
        sum(a) / a.length.to_f
      end
    
      def self.sample_variance(a)
        m = mean(a)
        sum = a.inject(0){ |accum, i| accum + (i - m) ** 2 }
        sum / (a.length - 1).to_f
      end
    
      def self.standard_deviation(a)
        Math.sqrt(sample_variance(a))
      end
    end
    

    And then you use it as such:

    2.0.0p353 > MyApp::Maths.standard_deviation([1,2,3,4,5])
    => 1.5811388300841898
    
    2.0.0p353 :007 > a = [ 20, 23, 23, 24, 25, 22, 12, 21, 29 ]
     => [20, 23, 23, 24, 25, 22, 12, 21, 29]
    
    2.0.0p353 :008 > MyApp::Maths.standard_deviation(a)
     => 4.594682917363407
    
    2.0.0p353 :043 > MyApp::Maths.standard_deviation([1,2,2.2,2.3,4,5])
     => 1.466628787389638
    

    The behavior is the same, but it avoids the overheads and risks of adding methods to Enumerable.

提交回复
热议问题