2015-07-12 136 views
4

对于一个相对较大的熊猫数据框(几十万行),我想创建一个应用函数的结果系列。问题是这个函数不是很快,我希望它能以某种方式加快速度。加速熊猫应用函数

df = pd.DataFrame({ 
'value-1': [1, 2, 3, 4, 5], 
'value-2': [0.1, 0.2, 0.3, 0.4, 0.5], 
'value-3': somenumbers..., 
'value-4': more numbers..., 
'choice-index': [1, 1, np.nan, 2, 1] 
}) 

def func(row): 
    i = row['choice-index'] 
    return np.nan if math.isnan(i) else row['value-%d' % i] 

df['value'] = df.apply(func, axis=1, reduce=True) 

# expected value = [1, 2, np.nan, 0.4, 5] 

欢迎任何建议。

更新

一个非常小的加速比(〜1.1)可通过预缓存选中的列来实现。

cached_columns = [None, 'value-1', 'value-2', 'value-3', 'value-4'] 
def func(row): 
    i = row['choice-index'] 
    return np.nan if math.isnan(i) else row[cached_columns[i]] 

,但我希望更大的加速......

+0

,您是否试图用Cython,numba,EVAL + numexpr在http://pandas.pydata.org/pandas-docs/stable/enhancingperf.html – denfromufa

+0

不建议,不为这个特殊的问题。但我认为主要的问题是调用apply函数的次数,所以'cython','numba','numexpr'等对缓解这个问题无济于事。 – orange

回答

4

我想我有一个很好的解决方案(加速〜150):到func会改变。

诀窍是不要使用apply,而是做智能选择。

choice_indices = [1, 2, 3, 4] 
for idx in choice_indices: 
    mask = df['choice-index'] == idx 
    result_column = 'value-%d' % (idx) 
    df.loc[mask, 'value'] = df.loc[mask, result_column]