5

我想要一个可以采用一系列和一组垃圾箱的函数,并且基本上四舍五入到最近的垃圾箱。例如:

my_series = [ 1, 1.5, 2, 2.3,  2.6,  3]
def my_function(my_series, bins):
    ...

my_function(my_series, bins=[1,2,3])
> [1,2,2,3,3,3]

这似乎非常接近Numpy 的 Digitize打算做的事情,但它产生了错误的值(错误值的星号):

np.digitize(my_series, bins= [1,2,3], right=False)
> [1, 1*, 2, 2*, 2*, 3]

从文档中可以清楚地看出错误的原因:

i 返回的每个索引使得bins[i-1] <= x < bins[i]如果 bins 单调递增,或者bins[i-1] > x >= bins[i]如果 bins 单调递减。如果 x 中的值超出 bin 的范围,则根据需要返回 0 或 len(bins)。如果 right 为 True,则右 bin 关闭,以便索引 i 满足 bins[i-1] < x <= bins[i] 或 bins[i-1] >= x > bins[i]``如果 bins 分别单调递增或递减。

如果我输入递减的值并将“正确”设置为True,我可以更接近我想要的东西......

np.digitize(my_series, bins= [3,2,1], right=True)
> [3, 2, 2, 1, 1, 1]

但随后我将不得不想出一种方法,基本上有条不紊地将最低编号分配 (1) 与最高编号分配 (3) 颠倒过来。当只有 3 个垃圾箱时这很简单,但当垃圾箱的数量变长时会变得更毛茸茸……必须有一种更优雅的方式来完成这一切。

4

3 回答 3

3

我们可以简单地使用np.digitize它的right选项集True来获取索引,然后提取相应的元素bins,引入np.take,就像这样 -

np.take(bins,np.digitize(a,bins,right=True))
于 2016-09-08T18:25:46.980 回答
1

另一种方法是:

In [25]: def find_nearest(array,value):
    ...:     idx = (np.abs(array-np.ceil(value))).argmin()
    ...:     return array[idx]
    ...: 

In [26]: my_series = np.array([ 1, 1.5, 2, 2.3,  2.6,  3])

In [27]: bins = [1, 2, 3]

In [28]: [find_nearest(bins, x) for x in my_series]
Out[28]: [1, 2, 2, 3, 3, 3]
于 2016-09-08T04:44:52.547 回答
1

我相信np.searchsorted会做你想做的事:

找到排序数组中的索引a,这样,如果在v索引之前插入相应的元素,则将保留 a 的顺序。

In [1]: my_series = [1, 1.5, 2, 2.3, 2.6, 3]

In [2]: bins = [1,2,3]

In [3]: import numpy as np

In [4]: [bins[k] for k in np.searchsorted(bins, my_series)]
Out[4]: [1, 2, 2, 3, 3, 3]

(从 numpy 1.10.0 开始,digitize按照 .)实现searchsorted。)

于 2016-09-08T04:42:45.197 回答