我有一个排名函数,我应用于数百万行的大量列,需要几分钟才能运行.通过删除准备数据以应用该.rank(
方法的所有逻辑,即通过这样做:
ranked = df[['period_id', 'sector_name'] + to_rank].groupby(['period_id', 'sector_name']).transform(lambda x: (x.rank(ascending = True) - 1)*100/len(x))
Run Code Online (Sandbox Code Playgroud)
我设法把它降到了几秒钟.但是,我需要保留我的逻辑,并且正在努力重构我的代码:最终,最大的瓶颈是我对lambda x:的双重使用,但显然其他方面正在减慢速度(见下文).我提供了一个示例数据框,以及下面的排名函数,即MCVE.从广义上讲,我认为我的问题归结为:
(i)如何.apply(lambda x
用快速的矢量化等价替换代码中的用法?(ii)如何循环多索引,分组,数据帧并应用函数?就我而言,对于date_id和category列的每个唯一组合.
(iii)我还能做些什么来加快我的排名逻辑?主要的开销似乎是在.value_counts()
.这与上面的(i)重叠; 也许在发送排名之前,可以通过构建临时列来在df上完成大部分逻辑操作.同样,可以在一次调用中对子数据帧进行排名吗?
(iv)为什么要使用pd.qcut()
而不是df.rank()
?后者是cython化的,似乎有更灵活的关系处理,但我看不出两者之间的比较,pd.qcut()
似乎最广泛使用.
样本输入数据如下:
import pandas as pd
import numpy as np
import random
to_rank = ['var_1', 'var_2', 'var_3']
df = pd.DataFrame({'var_1' : np.random.randn(1000), 'var_2' : np.random.randn(1000), 'var_3' : np.random.randn(1000)})
df['date_id'] = np.random.choice(range(2001, 2012), df.shape[0])
df['category'] = ','.join(chr(random.randrange(97, 97 + 4 + 1)).upper() for x in range(1,df.shape[0]+1)).split(',')
Run Code Online (Sandbox Code Playgroud)
这两个排名功能是:
def rank_fun(df, …
Run Code Online (Sandbox Code Playgroud) 假设我有两个数组A
和B
,其中两个A
和B
的m x n
.我的目标是现在,对于每一行A
和B
,找到我应该在哪里插入行的元素i
中A
的相应行中B
.也就是说,我希望申请np.digitize
或np.searchsorted
每行A
和B
.
我天真的解决方案是简单地迭代行.但是,这对我的应用来说太慢了.因此,我的问题是:是否存在我无法找到的算法的矢量化实现?