【发布时间】:2018-09-19 06:49:55
【问题描述】:
我有一个非常大的一维数组,其中大多数元素为零,而非零元素都聚集在由许多零分隔的几个岛周围:(这里是一个较小的版本,用于 MWE)
In [1]: import numpy as np
In [2]: A=np.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,6,20,14,10,5,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,4,5,5,18,18,16,14,10,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,3,6,16,4,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])
我想根据每个岛的中值对应的索引找到中值及其位置(甚至是近似值)。毫不奇怪,我得到了零,这不是我想要的:
In [3]: np.median(A)
Out[3]: 0.0
In [4]: np.argsort(A)[len(A)//2]
Out[4]: 12
在单个非零元素岛的情况下,为了解决这个警告并满足我的要求,即只有非零元素在物理上有意义,我首先删除所有零,然后取剩余元素的中位数:
In [5]: masks = np.where(A>0)
In [6]: A[masks]
Out[6]: array([ 1, 3, 6, 20, 14, 10, 5, 1])
这一次,我正确地得到了新数组的中位数,但是位置(索引)将不正确,因为它很明显,并且在 cmets 中也指出在数学上定义不明确。
In [7]: np.median(A[masks])
Out[7]: 5.5
In [8]: np.argsort(A[masks])[len(A[masks])//2]
Out[8]: 2
根据这个近似值,我知道实际中位数位于修改后数组的第三个索引中,但我想将其转换回原始数组的格式,其中中位数的位置(索引)应该在某处在对应于较大索引的非零元素的第一个岛的中间(其中零索引都被正确计算)。在 cmets 中还回答了两个建议,以在零海中间给定一个非零元素岛的情况下提出中位数的位置。但是,如果有不止一个这样的岛屿呢?怎么可能在原始的直方图数组的上下文中计算每个岛的中位数对应的索引,其中所有的零都被计算在内?
我想知道是否有任何简单的方法来计算这些许多零的数组中的中位数的位置。如果没有,在知道修改后的数组中的位置后,我还应该在我的代码行中添加什么以使其成为可能?非常感谢您的帮助。
【问题讨论】:
-
np.median(masks)怎么样?预期的 o/p 是多少?如果有多个非零岛的情况如何? -
亲爱的沃伦,你是对的。但我只对非零元素感兴趣。但我碰巧需要的唯一一条信息是在原始数组中用零定位这个中值。我猜 Divakar 的评论将被视为一个答案。
-
亲爱的 Miradulo,这将给我提供两倍大的东西。
-
中位数的“位置”不是一个明确定义的量。
[3, 8, 9, 7, 2, 1, 9, 7]的中位数是 7,但是如何定义它的位置呢? -
A实际上是一个直方图(即一个计数数组),你想要计算值的中位数吗?那么也许像np.searchsorted(A.cumsum(), A.sum()/2)这样的东西会起作用。
标签: python-3.x sorting numpy indexing median