我正在尝试使用apply函数在我的数据帧的一个子集上创建一个相对较小(~600行)的新列,它可以工作,但它很慢,因为apply函数是计算密集型的,我无法制作这个黑盒功能更快/更简单。
然而,这个黑盒函数返回的很多结果实际上是相同的(接近90%)因为输入是相同的。因此,如果给定的输入相同以节省时间,是否可以简单地重复使用返回的值?
以下代码有效,但速度很慢:
df.loc[df['number']>=10, 'value'].apply(lambda x: black_box(x).get())
同样,列value
中的大多数值都相同,从而产生相同的输出。
答案 0 :(得分:1)
斯科特的建议很好,另一个选择是使用GroupBy.transform
:
s = df.loc[df['number'] >= 10, 'value']
s.groupby(s).transform(lambda g: black_box(g.name).get())
这仅对每个组应用一次函数,但返回一系列与调用者相同的形状。
编辑:时间比较(使用Scott的示例)
s = df['key']
%timeit s.groupby(s).transform(lambda g: factorial(g.name))
# 100 loops, best of 3: 3.92 ms per loop
%timeit df['result'] = df.key.map(dict)
# 100 loops, best of 3: 2.22 ms per loop
答案 1 :(得分:1)
MVCE示例:
df = pd.DataFrame({'key':np.random.randint(1,10,60000),'result':np.nan})
def factorial(x): #Black box
accum = 1
for i in range(1,x+1):
accum *= i
return accum
%timeit df['result'] = df.key.apply(lambda x: factorial(x))
10个循环,每个循环最佳3:120毫秒
使用黑框创建唯一值字典:
def fact_d(values):
d = {}
for i in values:
d[i] = factorial(i)
return d
dict = fact_d((df.key.unique().tolist()))
将字典映射到dataframe:
%timeit df['result'] = df.key.map(dict)
100个循环,最佳3:每循环6.22毫秒