【问题标题】:How to find the median of different-sized lists如何找到不同大小列表的中位数
【发布时间】: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 的大小足够大,它们至少会变化一个。)

标签: python numpy


【解决方案1】:

只需将您的两列放在pandas DataFrame 中,您就可以通过按“索引”分组轻松计算中位数。让我们在实践中看到它:

import numpy as np , pandas as pd

indices = [0,1,1,1,3,1,1,0,0,0,3]
data = np.arange(len(indices))

df = pd.DataFrame({"indices": indices, "data": data}) # Your DataFrame
df.head() # Take a look

    indices data
0   0   0
1   1   1
2   1   2
3   1   3
4   3   4
medians = df.groupby("indices").median()# median for each value of `indices`
medians  
        data
    indices 
    0   7.5
    1   3.0
    3   7.0

# Finding indices with no data point
desired_indices = pd.Series([0, 1, 10, -5, 2])
is_in_index = desired_indices.isin(medians.index)
has_no_data = desired_indices[~ is_in_index]
has_no_data
2    10
3    -5
4     2
dtype: int64

【讨论】:

  • 辉煌;这样做了,并且在我的大型数据集上大约需要一秒钟,而 for 循环需要几个小时。后续行动:有没有一种简单的方法可以识别没有数据的垃圾箱? (我真的想要 bin 2 中的 nan,并且我希望 bin 以索引顺序排列。)
  • 我添加了一段代码来查找没有数据点的索引。你可以吗?
  • 是的。我做了一个小的编辑来结合索引有和没有数据。谢谢!
猜你喜欢
  • 2021-05-06
  • 1970-01-01
  • 2021-08-24
  • 1970-01-01
  • 2021-08-19
  • 1970-01-01
  • 2012-06-01
  • 2016-03-12
  • 2018-05-14
相关资源
最近更新 更多