按值拆分为等份

Split to equal parts by values

有没有一种方便的分割数组的方法,无论每个部分的元素数量如何,它包含的值的范围都是相同的?

假设我们有 (0, 100) 范围内的数据。设数组大小为1000,前500个元素都在(0, 20),后300个元素在(20, 40),以此类推。我想操纵按 20、40、60 和 80 分割的小节中的值。

数据可能如下所示:

1st div:  0,  0,  0, ... 17, 18
2nd div: 22, 22, 24, ... 37, 39
3rd div: 40, 41, 41, ... 55, 59
4th div: 65, 68, 73, 76, 76
5th div: 93, 96

按节大小将数组分成大小相等的节非常容易。但我正在使用一些简单的平均值绘制趋势线,每个部分的数据量各不相同。我知道分裂点。

它可以用 np.where 来制作,条件是 arr > border1 只取第一个元素,合并然后拆分,但这似乎是一种很长的做事方式。

任何指点将不胜感激。我不能是唯一遇到这个问题的人。另外,如果另一个图书馆做这种事情,我当然愿意使用它。

使用 np.searchsorted 获取将拆分成组的索引,然后使用 np.split -

拆分这些索引
In [41]: np.random.seed(0)

In [42]: a = np.sort(np.random.randint(0,100,(10000)))

In [43]: bins = [20,40,60,80]

In [46]: idx = np.searchsorted(a, bins)

In [47]: np.split(a,idx)
Out[47]: 
[array([ 0,  0,  0, ..., 19, 19, 19]),
 array([20, 20, 20, ..., 39, 39, 39]),
 array([40, 40, 40, ..., 59, 59, 59]),
 array([60, 60, 60, ..., 79, 79, 79]),
 array([80, 80, 80, ..., 99, 99, 99])]

如果输入的元素已经排序,考虑使用groupby:

import itertools

l=[0,1,5,17,18,22,27,37,39,40,41,48,57,65,68,72,77,79,81,85,88,91,99]

for k, v in itertools.groupby(l, key=lambda x: x//20):
    # k=0, v=[0, 1, 5, 17, 18]
    # k=1, v=[22, 27, 37, 39]
    # k=2, v=[40, 41, 48, 57]
    # ...