Numpy / pandas优化:bins计数

时间:2016-07-04 10:11:22

标签: python numpy pandas optimization lambda

我希望通过计算numpy.arraypandas.Series之间值x来{bin} Nbegin end 。结果存储在pandas.DataFrame

import numpy as np
import pandas as pd
bins = pd.DataFrame({'from': np.arange(0, 1, 0.01), 'to': np.arange(0, 1, 0.01) + 0.1})
x = np.random.rand(1000000)
bins['N'] = bins.apply(lambda r:  ((x >= r['from']) & (x < r['to'])).sum(), axis=1)

当我分析代码时,整个脚本中最慢的部分(包含更多东西),如果最后一行,特别是lambda:15%的时间花在该lambda中!

我感觉不是使用lambda,而是必须以矢量化方式实现,但我无法弄清楚如何。

我使用的是Python 3.5,numpy 1.11和pandas 0.18.1

编辑:附加信息+使用intervaltree进行测试

实际上,迭代使用了分箱:分箱是用一些数据启动的,可能会用其他数据集更新。

正如所建议的那样,我尝试过使用intervaltree,但它在性能方面甚至变得更糟。从第二次迭代开始,我收到了一个用户arning,因为boold dtype上的numexpr不支持'+',所以它切换到纯python模式。

2 个答案:

答案 0 :(得分:3)

间隔具有常规大小的事实可能会被滥用以加快代码的速度。因此,通过设置参数,您可以使用NumPy's bincount procedure,如此 -

covertPoint:

因此,对于发布的样本,我们将使用params:

UICollectionView

示例运行 -

# First off, filter out elements that are outside the min,max limits.
# Then subtract min_val from the filtered elements so that they all start from 0
# Then, scale them w.r.t width and floor them, thus converting them into IDs
IDs = ((x[(x >= min_val) & (x<=max_val)]-min_val)/width).astype(int)

# Finally count those IDs, which is the desired output as new column
bins['N'] = np.bincount(IDs)

答案 1 :(得分:2)

如果“...边界有固定宽度,如[[min + 0 width,min + 1 width],[min + 1 width,min + 2 width],...,[max - 1 width,max]] ...“,使用numpy.histogram

bins["N"] = numpy.histogram(x, numpy.concatenate([bins["from"], bins["to"].tail(1)]))[0]

这比这更简单,但是如果你在bin [“to”]中有最后一个边缘,你需要将它包含在bin边缘列表中。

详细信息:http://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html