【问题标题】:A median that doesn't divide the sum of two elements in cases when there is an even number of elements在元素个数为偶数的情况下不除以两个元素之和的中位数
【发布时间】:2020-06-18 20:27:34
【问题描述】:

尝试搜索,但没有找到任何相关内容。假设我们有一个包含偶数个数的序列,我们想计算它的中位数:

pd.Series([4, 6, 8, 10]).median()

因为我们有偶数个元素,所以没有元素正好在中间,因此该方法执行计算:(6 + 8) / 2 = 7。但是,对于我的目的,非常重要的是中位数是系列中已经存在的数字,不能从头开始计算。所以我宁愿选择 6 或 8 而不是使用 7。

其中一种可能的解决方案是检测存在偶数个元素的事实,在这种情况下,添加另一个保证为最大或最小的元素,然后在我得到中位数。但是即使对于一个系列的情况,这种解决方案也显得相当笨拙。如果我们要处理的是 SeriesGroupBy 对象,其中必须为每个组分别计算这样的中位数,我什至无法想象如何实现它。

看起来median() 方法中没有参数使它选择两个最近的元素之一而不是除法,而且我找不到任何可以替代median() 方法的替代方法。实现我自己的中值函数是我唯一的选择吗?

【问题讨论】:

  • 一定要用pandas吗?
  • 我找不到其他方法。但是定义一个函数非常容易。
  • 没有熊猫它只是sorted(l)[len(l)//2]
  • @Barmar 实际上是sorted(l)[ceil(len(l)/2)]。如果使用sorted(l)[len(l)//2],当列表元素个数为奇数时,会返回不准确的中位数。

标签: python pandas median


【解决方案1】:

您可能应该使用分位数选项而不是使用中位数(默认为中位数,即 0.5 分位数),并将插值设置为更高、更低或最近。

例如

>>> pd.Series([4, 6, 8, 10]).quantile(q=0.5, interpolation='nearest')
8
>>> pd.Series([4, 6, 8, 10]).quantile(q=0.5, interpolation='higher')
8
>>> pd.Series([4, 6, 8, 10]).quantile(q=0.5, interpolation='lower')
6

【讨论】:

  • @UchuuStranger 哎呀,很高兴你(和特伦顿)发现了返回值错字。仅供参考,当您的分位数为 0.5 和偶数个索引时,看起来最接近的选择上限值,但如果您稍微超过或低于 0.5 分位数,则最接近的明确确定最接近的分数,如文档中所述。
【解决方案2】:

如果你不需要使用pandas,你可以简单地对列表进行排序,然后获取中间元素。使用整数除法确保您得到一个没有分数的实际索引。

def list_median(l):
    if len(l) == 0:
        return None # or maybe raise an error
    return sorted(l)[(len(l) - 1) // 2]

例子:

如果列表长度为7(奇数),则媒体为索引3,(len(l) - 1) // 2) == 3

如果列表长度为8(偶数),则中位数在索引 3 和 4 之间,而(len(l) - 1) // 2) == 3 是这两个索引中的第一个。

【讨论】:

  • 我确实需要使用 pandas,因为我需要将此函数应用于 SeriesGroupBy 对象。尝试通过 apply() 方法使用您的版本。它有效,但仅适用于没有任何缺失值的子系列,您的函数不考虑它们。 quantile() 方法可以,所以这就是我要使用的方法。不过谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-27
  • 1970-01-01
  • 2021-12-28
相关资源
最近更新 更多