我正在DataFrame上执行复杂转换。我认为这对Pandas来说会很快,但我设法做到的唯一方法是使用lambda函数嵌套groupbys和applys,而且速度很慢。这看起来应该是内置的,更快的方法。在n_rows = 1000时,它是2秒,但我会做10^7行,所以这太慢了。这是很难解释我们在做什么,所以这里的代码和配置文件,然后我会解释:极品速度:缓慢嵌套群组并应用于熊猫
n_rows = 1000
d = pd.DataFrame(randint(1,10,(n_rows,8))) #Raw data
dgs = array([3,4,1,8,9,2,3,7,10,8]) #Values we will look up, referenced by index
grps = pd.cut(randint(1,5,n_rows),arange(1,5)) #Grouping
f = lambda x: dgs[x.index].mean() #Works on a grouped Series
g = lambda x: x.groupby(x).apply(f) #Works on a Series
h = lambda x: x.apply(g,axis=1).mean(axis=0) #Works on a grouped DataFrame
q = d.groupby(grps).apply(h) #Slow
824984 function calls (816675 primitive calls) in 1.850 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
221770 0.105 0.000 0.105 0.000 {isinstance}
7329 0.104 0.000 0.217 0.000 index.py:86(__new__)
8309 0.089 0.000 0.423 0.000 series.py:430(__new__)
5375 0.081 0.000 0.081 0.000 {method 'reduce' of 'numpy.ufunc' objects}
34225 0.068 0.000 0.133 0.000 {method 'view' of 'numpy.ndarray' objects}
36780/36779 0.067 0.000 0.067 0.000 {numpy.core.multiarray.array}
5349 0.065 0.000 0.567 0.000 series.py:709(_get_values)
985/1 0.063 0.000 1.847 1.847 groupby.py:608(apply)
5349 0.056 0.000 0.198 0.000 _methods.py:42(_mean)
5358 0.050 0.000 0.232 0.000 index.py:332(__getitem__)
8309 0.049 0.000 0.228 0.000 series.py:3299(_sanitize_array)
9296 0.047 0.000 0.116 0.000 index.py:1341(__new__)
984 0.039 0.000 0.092 0.000 algorithms.py:105(factorize)
组数据框行被分组。对于每一个分组,对于每一行,按照那些相同的值进行分组(即,全部具有值3而所有值都具有值4)。对于值分组中的每个索引,请在dgs
中查找相应的索引和平均值。然后平均为行分组。
::呼气::
如何重新安排这一速度将不胜感激任何建议。
伟大的标题选择 – qwr
做一个嵌套的嵌套应用/分组这样做是不是答案。这几乎是纯Python代码,你没有利用任何熊猫的优势。您可能想要在顶层组合groupby(或构建多索引),选择要包含的值,然后使用cythonized函数来应用它。你只想做1级的groupby并申请(除非在一些非常罕见的情况下)。你最终正在做一些矢量化的操作,但是你在最底层的时候正在向后做。 – Jeff