【发布时间】:2019-05-16 05:59:55
【问题描述】:
我有一个数字列表,我想将它们分类到 bin 中并找到每个 bin 的中位数。如果这些 bin 都具有相同数量的数据点,那么使用 numpy 数组可以很容易地合理有效地做到这一点:
import numpy as np
indices=np.array([0,1,0,1,1,2,3,3,3,2,0,2])
length=np.max(indices)+1
data = np.arange(len(indices))
binned = np.array([data[indices == i] for i in range(length)])
分箱数据(在数组binned中)是
array([[ 0, 2, 10],
[ 1, 3, 4],
[ 5, 9, 11],
[ 6, 7, 8]])
每个 bin 的中位数是:
np.median(binned, axis=1)
结果:
array([2., 3., 9., 7.])
但是,如果列表中每个 bin 中有不同数量的点(或某些 bin 中没有点),我无法创建 numpy 数组或使用 np.median 而是必须执行for 循环中的繁重工作:
indices=np.array([0,1,1,1,3,1,1,0,0,0,3])
data = np.arange(len(indices))
分箱数据是
[data[indices == i] for i in range(length)]
[array([0, 7, 8, 9]),
array([1, 2, 3, 5, 6]),
array([], dtype=int64),
array([ 4, 10])]
但我不能取数组列表的中位数。相反,我可以这样做
[np.median(data[indices == i]) for i in range(length)]
得到
[7.5, 3.0, nan, 7.0]
但是那个 for 循环非常慢。 (我的真实数据中有几百万个数据点和数万或数十万个 bin。)
有没有办法避免过度依赖 for 循环(甚至完全摆脱 for 循环)?
【问题讨论】:
-
通过确定大小的函数更改 4
-
完成。 (将 4 更改为
length)。 -
我认为不会有不同的方法来获取不同大小列表的中位数。如果存在一种方法,它将是一个包装器,因为对于不同的大小,您需要考虑不同的算法,这实际上是一个 for 循环。
-
根据 bin 大小的多样性,将相同大小的 bin 组合在一起可能会很有用。
-
有趣的想法@MichaelButscher,但在我的特定情况下可能不会有很多(如果有的话)相同大小的垃圾箱。 (数百万个数据点被分组到数以万计的 bin 中,因此 bin 的大小足够大,它们至少会变化一个。)