在 Ruby 中计算中位数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14859120/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 05:44:58  来源:igfitidea点击:

Calculating Median in Ruby

rubymedian

提问by tomgalpin

How do I calculate the median of an array of numbers using Ruby?

如何使用 Ruby 计算一组数字的中位数?

I am a beginner and within the progress of my learning I am trying to stick to what has already been taught. Thus the other questions that I've found are beyond my scope.

我是一个初学者,在我学习的过程中,我试图坚持已经教过的东西。因此,我发现的其他问题超出了我的范围。

Here are my notes and my attempt:

这是我的笔记和我的尝试:

  1. sort the array in ascending order.
  2. figure out if it is odd or even in length.
  3. if odd, divide the sorted array length +1 in half. That is the index of the median. Return this value.
  4. if even, find the middle two numbers of the sorted array and divide them in 1/2. Return this value.
  5. Finding the middle two numbers:
  6. divide the sorted array length in half. This is index pt. first middle number.
  7. divide sorted array length + 2 in half. This is the index pt. of the second middle number.
  8. take average of these two middle numbers.

    def median(array)
      ascend = array.sort
      if ascend % 2 != 0
        (ascend.length + 1) / 2.0
      else
        ((ascend.length/2.0) + ((ascend.length + 2)/2.0) / 2.0)
      end
    end
    
  1. 按升序对数组进行排序。
  2. 弄清楚它的长度是奇数还是偶数。
  3. 如果是奇数,则将排序后的数组长度 +1 一分为二。那是中位数的指数。返回这个值。
  4. 如果偶数,则找到已排序数组的中间两个数字并将它们除以 1/2。返回这个值。
  5. 找到中间的两个数字:
  6. 将排序后的数组长度一分为二。这是索引 pt。第一个中间数字。
  7. 将排序后的数组长度 + 2 分成两半。这是索引pt。第二个中间数字。
  8. 取这两个中间数字的平均值。

    def median(array)
      ascend = array.sort
      if ascend % 2 != 0
        (ascend.length + 1) / 2.0
      else
        ((ascend.length/2.0) + ((ascend.length + 2)/2.0) / 2.0)
      end
    end
    

回答by nbarraille

Here is a solution that works on both even and odd length array and won't alter the array:

这是一个适用于偶数和奇数长度数组并且不会改变数组的解决方案:

def median(array)
  sorted = array.sort
  len = sorted.length
  (sorted[(len - 1) / 2] + sorted[len / 2]) / 2.0
end

回答by AnkitG

If by calculating Median you mean this

如果通过计算中值你的意思是这个

Then

然后

a = [12,3,4,5,123,4,5,6,66]
a.sort!
elements = a.count
center =  elements/2
elements.even? ? (a[center] + a[center+1])/2 : a[center]  

回答by Kal

Similar to nbarraille's, but I find it a bit easier to keep track of why this one works:

与 nbarraille 类似,但我发现跟踪它为什么有效更容易一些:

class Array
  def median
    sorted = self.sort
    half_len = (sorted.length / 2.0).ceil
    (sorted[half_len-1] + sorted[-half_len]) / 2.0
  end
end

half_len = number of elements up to and including (for array with odd number of items) middle of array.

half_len = 直到并包括(对于具有奇数个项目的数组)数组中间的元素数。

Even simpler:

更简单:

class Array
  def median
    sorted = self.sort
    mid = (sorted.length - 1) / 2.0
    (sorted[mid.floor] + sorted[mid.ceil]) / 2.0
  end
end

回答by Kyle Snow Schwartz

  def median(array)                          #Define your method accepting an array as an argument. 
      array = array.sort                     #sort the array from least to greatest
      if array.length.odd?                   #is the length of the array odd?
        array[(array.length - 1) / 2] #find value at this index
      else array.length.even?                #is the length of the array even?
       (array[array.length/2] + array[array.length/2 - 1])/2.to_f
                                             #average the values found at these two indexes and convert to float
      end
    end

回答by Alexander

More correct solution with handling edge cases:

处理边缘情况的更正确的解决方案:

class Array
  def median
    sorted = self.sort
    size = sorted.size
    center = size / 2

    if size == 0
      nil
    elsif size.even?
      (sorted[center - 1] + sorted[center]) / 2.0
    else
      sorted[center]
    end
  end
end

There is a specs to prove:

有一个规范可以证明:

describe Array do
  describe '#median' do
    subject { arr.median }

    context 'on empty array' do
      let(:arr) { [] }

      it { is_expected.to eq nil }
    end

    context 'on 1-element array' do
      let(:arr) { [5] }

      it { is_expected.to eq 5 }
    end

    context 'on 2-elements array' do
      let(:arr) { [1, 2] }

      it { is_expected.to eq 1.5 }
    end

    context 'on odd-size array' do
      let(:arr) { [100, 5, 2, 12, 1] }

      it { is_expected.to eq 5 }
    end

    context 'on even-size array' do
      let(:arr) { [7, 100, 5, 2, 12, 1] }

      it { is_expected.to eq 6 }
    end
  end
end

回答by Zoh

def median(arr)
    sorted = arr.sort 
    if sorted == []
       return nil
    end  

    if sorted.length % 2 != 0
       result = sorted.length / 2 # 7/2 = 3.5 (rounded to 3)
       return sorted[result] # 6 
    end

    if sorted.length % 2 == 0
       result = (sorted.length / 2) - 1
       return (sorted[result] + sorted[result+1]) / 2.0 #  (4 + 5) / 2
    end
end

p median([5, 0, 2, 6, 11, 10, 9])

回答by Nana

Here's a solution:

这是一个解决方案:

app_arry = [2, 3, 4, 2, 5, 6, 16].sort

# check array isn't empty
if app_arry.empty?  || app_arry == ""
  puts "Sorry, This will not work."
  return nil
end

length = app_arry.length
puts "Array length = #{length}"
puts "Array = #{app_arry}"

if length % 2  == 0
 # even number of elements
 puts "median is #{(app_arry[length/2].to_f +  app_arry[(length-1)/2].to_f)/2}"
else
 # odd number of elements
 puts "median is #{app_arry[(length-1)/2]}"
end

OUTPUT

输出

Array length = 7

Array = [2, 3, 4, 2, 5, 6, 16]

median is 2

数组长度 = 7

数组 = [2, 3, 4, 2, 5, 6, 16]

中位数是 2

回答by Yashvi Patel

def median(array, already_sorted=false)
    return nil if array.empty?
    array = array.sort unless already_sorted
    m_pos = array.size / 2
    return array.size % 2 == 1 ? array[m_pos] : mean(array[m_pos-1..m_pos])
end

回答by user3007294

def median(array)
  half = array.sort!.length / 2
  array.length.odd? ? array[half] : (array[half] + array[half - 1]) / 2 
end

*If the length is even, you must add the middle point plus the middle point - 1 to account for the index starting at 0

*如果长度为偶数,则必须加上中点加上中点-1来占索引从0开始

回答by whatzzz

I think it's good:

我觉得很好:

#!/usr/bin/env ruby

#in-the-middle value when odd or
#first of second half when even.
def median(ary)
  middle = ary.size/2
  sorted = ary.sort_by{ |a| a }
  sorted[middle]
end

or

或者

#in-the-middle value when odd or
#average of 2 middle when even.
def median(ary)
  middle = ary.size/2
  sorted = ary.sort_by{ |a| a }
  ary.size.odd? ? sorted[middle] : (sorted[middle]+sorted[middle-1])/2.0
end

I used sort_by rather than sort because it's faster: Sorting an array in descending order in Ruby.

我使用 sort_by 而不是 sort 因为它更快:在 Ruby 中按降序对数组进行排序