如何在具有偶数个条目的numpy掩码数组中获取单个中位数

4

我有一个Numpy的掩码多维数组。我需要在特定轴上找到中位数。对于某些情况,我最终得到元素数量为偶数,在这种情况下numpy.ma.median会给出中间两个元素的平均值。但是,我不想要平均值。我想要其中一个中位数元素。任何一个都可以。我该怎么做?

代码示例:

>>> import numpy
>>> data=numpy.arange(-5,10).reshape(3,5)
>>> mdata=numpy.ma.masked_where(data<=0,data)
>>> numpy.ma.median(mdata, axis=0)
masked_array(data=[5.0, 3.5, 4.5, 5.5, 6.5],
             mask=[False, False, False, False, False],
       fill_value=1e+20)

正如您所看到的,它正在对 (16) 进行平均,并提供小数值 (3.5)。我想要其中的任意一个 16


1
你所要求的不是中位数。 "中位数" 的定义是一组数据中,有一半的数据比它大,另一半比它小。如果元素数量为偶数,则选择其中一个元素后,上下两部分并不相等。 - Tim Roberts
好的,谢谢!你知道它叫什么吗?无论如何,我已经清楚表达了我的需求,对吧?有任何歧义需要我澄清吗? - Nagabhushan S N
1
对于偶数元素,中位数返回两个中间数字的平均值。然而,如果您不想要平均值,只想要其中任何一个中间数字,您可以在调用中位数方法时从集合中删除一个元素,这将使集合长度变为奇数,然后您将会在集合中找到一个可用的值,而不是平均值(尽管这不是一种正确的找中位数的方式)。 - Pranta Palit
正确。问题在于,没有正确答案。考虑集合[1,6],如果1或6是正确答案,那么你的结果怎么可能是可重复的呢?正如Pranta所说,只需删除一行即可获得所需结果。 - Tim Roberts
可通过始终选择较低的元素来实现可重复性。 - Nagabhushan S N
3个回答

2
对于元素数量为偶数的集合,中位数返回两个中间数字的平均值。但是,如果您不想要平均值,只想要其中任何一个中间数字,您可以在调用中位数方法时从您的集合中删除一个元素,这将使集合长度变为奇数,然后您将得到您想要的结果,而不是平均值(虽然这不是找到中位数的正确方式)。

根据整体上下文,考虑添加元素而不是删除,因为这样您可能更容易知道添加了哪个元素,并且可以在之后再次删除它,使原始数据“不受影响”。此外,从哪一侧删除/添加会影响中位数选择下一个较小或下一个较大的元素。我正在考虑这些事情,以匹配Numpy的中位数和IDL的中位数 - 因为我需要匹配IDL的输出,并且没有使用IDL的/EVEN选项。IDL显然选择下一个较大的元素。 - GG2
然而,添加元素的缺点是可能需要找出数据中的最小/最大值。 - GG2

0

当元素数量为偶数时,平均值应该是期望的结果。 假设您有一个由1到10的元素组成的数组。那么平均值应该是5和6的平均值,即5.5。如果您有从1到11的元素,则中位数为6。 希望这能澄清问题。


0
  • numpy.percentile(array, 50) 给出中位数。
  • numpy.percentile 有一个选项可以指定插值为 nearest
  • 但是,这个函数在 numpy.ma 模块中不可用。
  • this answer 中使用的技巧可以在这里使用。

思路是用 nan 填充无效的值,并使用带有 nearest 插值的 numpy.nanpercentile()

>>> mdata1 = numpy.ma.filled(mdata.astype('float'), numpy.nan)
>>> numpy.nanpercentile(mdata1, 50, axis=0, interpolation='nearest')
array([5., 1., 2., 3., 4.])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接