2016-09-12 13 views
0

私はnumpy.apply_along_axisのawesomne​​ssに慣れています。私は次のレベルにベクトル化することができるかどうか、主に速度目的のために、私が以下のコードで持っているforループを排除しようとしています。それを行うために最適化とnumpyのベクトル化:繰り返しの配列のセット

from pandas import DataFrame 
import numpy as np 
from time import time 

list_away = [] 

new_data_morphed = DataFrame(np.random.rand(1000, 5)).transpose().as_matrix() 
group_by_strat_full = DataFrame([ 
    [0, 1, 4], 
    [1, 2, 3], 
    [2, 3, 4], 
    [0, 1, 4]], columns=['add_mask_1', 'add_mask_2', 'add_mask_3', ]) 

all_the_core_strats = [lambda x: x.prod(), lambda x: sum(x), ] 

def run_strat_mod(df_vals, core_strat, dict_mask_1, dict_mask_2, dict_mask_3, list_away): 
    slice_df = df_vals[[dict_mask_1, dict_mask_2, dict_mask_3]] 
    # TODO: this comprehension list should be vectorized 
    to_append = [np.apply_along_axis(lambda x: u(x), 0, slice_df) for u in core_strat] 
    list_away.append(to_append) 

t1 = time() 
results_3 = group_by_strat_full.apply(lambda x: run_strat_mod(
    new_data_morphed, 
    all_the_core_strats, 
    x['add_mask_1'], 
    x['add_mask_2'], 
    x['add_mask_3'], 
    list_away), axis=1) 

t2 = time() 
print(abs(t1 - t2)) 

、私は配列の初期セットを繰り返すことを考えていた、それは私が新しいall_the_core_strats_modnumpy.apply_along_axisを適用することができるようにslice_dfです。これに

print(slice_df) 
    [[[ 0.91302268 0.6172959 0.05478723 ..., 0.37028638 0.52116891 
    0.14158221] 
    [ 0.72579223 0.78732047 0.61335979 ..., 0.46359203 0.27593171 
    0.73700975] 
    [ 0.21706977 0.87639447 0.44936619 ..., 0.44319643 0.53712003 
    0.8071096 ]] 

slice_df = np.array([df_vals[[dict_mask_1, dict_mask_2, dict_mask_3]]] * len(core_strat)) 
print(slice_df) 

[[[ 0.91302268 0.6172959 0.05478723 ..., 0.37028638 0.52116891 
    0.14158221] 
    [ 0.72579223 0.78732047 0.61335979 ..., 0.46359203 0.27593171 
    0.73700975] 
    [ 0.21706977 0.87639447 0.44936619 ..., 0.44319643 0.53712003 
    0.8071096 ]] 

[[ 0.91302268 0.6172959 0.05478723 ..., 0.37028638 0.52116891 
    0.14158221] 
    [ 0.72579223 0.78732047 0.61335979 ..., 0.46359203 0.27593171 
    0.73700975] 
    [ 0.21706977 0.87639447 0.44936619 ..., 0.44319643 0.53712003 
    0.8071096 ]]] 

、その後

def all_the_core_strats_mod(x): 
    return [x[0].prod(), sum(x[1])] 

to_append = np.apply_along_axis(all_the_core_strats_mod, 0, slice_df) 

が、私はそれぞれの重複に別々に(適用する機能を想像して、それが働いていない、この出力と

、ブロック)。

任意のアイデアは、あなたが簡単にするために、私が使用します3D配列、それを適用します(!より速く、より良い)歓迎

答えて

0
def foo(x): 
    print(x) # add for diagnosis 
    return [x[0].prod(), x[1].sum()] 

です:

In [64]: x=np.arange(2*3*2).reshape(2,3,2) 

In [66]: np.apply_along_axis(foo,0,x) 
[0 6] 
[1 7] 
[2 8] 
[3 9] 
[ 4 10] 
[ 5 11] 
Out[66]: 
array([[[ 0, 1], 
     [ 2, 3], 
     [ 4, 5]], 

     [[ 6, 7], 
     [ 8, 9], 
     [10, 11]]]) 

のでapply_along_axisをに渡していますfoo,x[:,0,0],x[:,0,1],x[:,1,0]などこれらの2つの数字にprodsumを入れることはそれほど刺激的ではありません。

apply_along_axisを行うための単なる便利な方法です:

for i in range(x.shape[1]): 
    for j in range(x.shape[2]): 
     ret[:,i,j] = foo(x[:,i,j]) 
関連する問題