【问题标题】:calculate median for a given input data and its frequencies计算给定输入数据及其频率的中位数
【发布时间】:2014-07-29 20:35:13
【问题描述】:

我得到以下输入:

num: counts
1:5
2:4
3:8

这是数频比:

为了计算这个输入的中位数,我做了一个简单的方法,用这些元素填充一个数组

>>>l = [1,1,1,1,1,2,2,2,2,3,3,3,3,3,3,3,3]
>>>i = len(l)/2
>>> median = l[i] if not i%2 else l[i+1]
>>> median
2

这是正确的。但是,我不必要地使用数组来填充。 我想知道是否有一种数学方法可以获得给定数字的中位数及其出现频率。

【问题讨论】:

  • 只是一个观察:您不需要 if-else 语句,只需执行 median = l[len(l)/2]
  • 是否总是按顺序提供值?是否可以在提供值之前知道值的数量?这些值是否在已知的有限范围内?
  • @MooingDuck:我们可以假设输入数据是排序的。但范围未知

标签: algorithm median


【解决方案1】:

您可以开始按顺序对频率求和,当总和超过总数的一半时,您会找到中位数。

counts = {1: 5, 2: 4, 3: 8}
total = sum(counts.values())
s = 0
for k in sorted(counts.keys()):
  s += counts[k]
  if s > total / 2:
    break
print 'median:', k

【讨论】:

    【解决方案2】:

    您需要准确的中位数还是估计的中位数。

    要获得准确的中位数,您可以迭代频率集并继续添加频率值。当总和大于总和的一半时,返回元素。 ruby 中的等价物(假设输入按键排序):

    def median(h)
      half = h.values.inject(:+).to_f/2
      sort = h.sort 
      sum = 0
      prev = 0
      sort.each do |k, v|
        if prev.nonzero?
          return (k + prev).to_f/2
        end
        sum+=v
        if sum == half 
          prev = k
        elsif sum > half
          return k
        end
      end
    end
    
    median({1=>5, 2 => 4, 3 => 8})
    

    存在一个计算估计媒体的公式

    median = l + ((n/2) − cfb)*w/fm
    

    在哪里

    • l 是包含中位数的组的下类边界
    • n是数据的总数
    • cfb 是中位数组之前各组的累积频率
    • fm 是中位数组的频率
    • w 是组宽

    【讨论】:

      【解决方案3】:

      假设您的输入已完全排序,就像您提供的输入一样,您可以这样做: 将每个数字的频率相加。如果是偶数,则除以 2。如果是奇数,则将频率加 1 并除以 2。在您提供的示例输入中,这样做会产生 9。

      现在对输入的频率求和,并在它们达到 9 时停止。在您停止的频率旁边的值 (num) 是您的中位数。在这种情况下,它是 2。

      【讨论】:

        【解决方案4】:

        您可以利用累积和(例如 pandas 或 numpy 中的 cumsum())。这是一个例子。

        import pandas as pd
        data = pd.Series([5,4,8], index = [1,2,3])
        
        
        data.sort_index()                   # sort just in case
        mid  = data.sum() / 2.0             # index of the middle element
        
        cum = data.cumsum()                 # cumulative sums of your data frequencies
        median = cum[cum >= mid].argmin()   # ignore the first half of the data and get the 
                                            # index of the median element
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-05-23
          • 1970-01-01
          • 1970-01-01
          • 2014-01-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多