我知道最好避免循环/迭代大熊猫系列。但是,对于我的用例,我无法找到合适的解决方案。
我有一个整数系列,如(100,101,103,102,99,100,102)等。我希望每当值向上移动时找到条目/索引。 3.对于上述迷你系列,它将是指数值(2,6)。
系统信息:Python版本:3.5.0 | Anaconda 2.5.0(64位)| (默认,2015年10月19日,21:57:25)[GCC 4.4.7 20120313(红帽4.4.7-1)],熊猫版:' 0.17.1'
这是我的代码,包括示例系列
cross apply
嗯,它有效,但由于我的真实世界问题有很多记录(> 25亿),这是一个非常缓慢的方法。我通过apply应用函数尝试了一些东西,但是由于参考值是动态设置的,所以找不到可行的解决方案。我也试着调查管道功能,但它让我很困惑。
因此,如果任何人有一些提示,以避免详尽的循环,我会非常高兴和感激。这是我的第一个问题,因为我还是一个新手,我希望我能很好地提出我的问题。
答案 0 :(得分:0)
这是一个更新,因为我找到了一个很好的解决方案。
我使用numba库显着提高了速度。很抱歉发布此答案,但我找不到我的编辑按钮:(
增强功能
%timeit getMoves_numba(系列) 100个循环,最佳3:9.72 ms每个循环
与纯Python相比
%timeit getMoves(系列) 1循环,最佳3:每循环1.87秒
我创建的示例系列有500万条记录。函数getMoves现在返回一个布尔索引数组供进一步使用......为了我的目的,10ms就足够了。只有一个声明是getMoves_numba = nb.autojit(getMoves)...很好:))
这是我的新代码:
import numpy as np
import numba as nb
def getMoves(v:np.array,points:int = 3, up:bool=True):
J=len(v)
refvalue=np.int
bound=np.int
result= np.zeros((J), dtype=bool)
if up == True:
refvalue=v[0]
bound=refvalue+points
for j in range(J):
if v[j] >= bound:
result[j]=True
refvalue = v[j]
bound=refvalue+points
elif v[j] < refvalue:
refvalue = v[j]
bound=refvalue+points
else:
refvalue=v[0]
bound=refvalue-points
for j in range(J):
if v[j] <= bound:
result[j]=True
refvalue = v[j]
bound=refvalue-points
elif v[j] > refvalue:
refvalue = v[j]
bound=refvalue-points
return result
np.random.seed(257931)
N=5000000
series=np.random.random_integers(-1,1,size=N)
series[0]=100
series=series.cumsum()
series = series + (abs(series.min())+1)
getMoves_numba = nb.autojit(getMoves)
这是在纯粹的numpy数组上完成的,所以如果在使用pandas系列时使用,我必须通过pandas.series.values传递它。
改善很好,但如果您对风格有提示或评论,我仍然会感谢一些反馈。
此致
C