我希望通过计算numpy.array
和pandas.Series
之间值x
来{bin} N
或begin
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模式。
答案 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