快速分类(分档)(fast categorization (binning))

2019-09-17 09:24发布

我有条目的数量巨大,每个人都是一个浮点数。 这些数据x是入店与迭代器。 我需要使用选择的所有条目进行分类等10<y<=2020<y<=50 ,....其中y是从其他iterables数据。 条目的数量比选择的数量多得多。 最后我想要一本字典,如:

{ 0: [all events with 10<x<=20],
  1: [all events with 20<x<=50], ... }

或类似的东西。 比如我做的:

for x, y in itertools.izip(variable_values, binning_values):
    thebin = binner_function(y)
    self.data[tuple(thebin)].append(x)

一般y是多维的。

这是非常缓慢的,是有一个更快的解决方案,例如使用numpy的? 我觉得从这个问题卡梅斯list.append我使用的方法,而不是从binner_function

Answer 1:

一个快速的方式来获得在numpy的工作分配使用np.digitize

http://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html

你仍然需要所产生的分配了分成组。 如果xy是多维的,你必须首先拼合的阵列。 然后,您可以得到独特的分档分配,然后遍历与结合np.where到的assigments起来分成不同的小组。 这可能会比较快,如果容器的数量比需要要合并元素的数量小得多。

作为一个有些简单的例子,你将需要调整/详细说明您的具体问题(而且是希望足以让你开始用numpy的解决方案):

In [1]: import numpy as np

In [2]: x = np.random.normal(size=(50,))

In [3]: b = np.linspace(-20,20,50)

In [4]: assign = np.digitize(x,b)

In [5]: assign
Out[5]: 
array([23, 25, 25, 25, 24, 26, 24, 26, 23, 24, 25, 23, 26, 25, 27, 25, 25,
       25, 25, 26, 26, 25, 25, 26, 24, 23, 25, 26, 26, 24, 24, 26, 27, 24,
       25, 24, 23, 23, 26, 25, 24, 25, 25, 27, 26, 25, 27, 26, 26, 24])

In [6]: uid = np.unique(assign)

In [7]: adict = {}

In [8]: for ii in uid:
   ...:     adict[ii] = np.where(assign == ii)[0]
   ...:     

In [9]: adict
Out[9]: 
{23: array([ 0,  8, 11, 25, 36, 37]),
 24: array([ 4,  6,  9, 24, 29, 30, 33, 35, 40, 49]),
 25: array([ 1,  2,  3, 10, 13, 15, 16, 17, 18, 21, 22, 26, 34, 39, 41, 42, 45]),
 26: array([ 5,  7, 12, 19, 20, 23, 27, 28, 31, 38, 44, 47, 48]),
 27: array([14, 32, 43, 46])}

对于扁平化处理,然后unflattening numpy的阵列,请参见: http://docs.scipy.org/doc/numpy/reference/generated/numpy.unravel_index.html

http://docs.scipy.org/doc/numpy/reference/generated/numpy.ravel_multi_index.html



Answer 2:

np.searchsorted是你的朋友。 正如我在另一个答案同一主题的这里的某个地方看,它比目前更快的数字化好位,并做相同的工作。

http://docs.scipy.org/doc/numpy/reference/generated/numpy.searchsorted.html



文章来源: fast categorization (binning)