2015-02-26 1 views
0

Excel Формулы Я пытаюсь повторить в панд: Click here to download workbook
* Посмотрите на столбцах D, E и Fкомплекс Excel Формула в панды

  • entsig и exsig ручные и могут быть изменены. В реальной жизни они будут получены из значения другого столбца или сравнения двух других столбцов

  • ent = 1, если entsig previous = 1 и in = 0

  • in = 1, если ent previous = 1 или (in previous = 1 и ex = 0)

  • ex = 1, если exsig previous = 1 и in previous = 1

  • так как ent, in или ex всегда будет = 1, но никогда не более чем один из них


import pandas as pd 
df = pd.DataFrame(
    [[0,0,0,0,0], [1,0,0,0,0], [1,0,0,0,0], [1,0,0,0,0], [0,0,0,0,0], 
    [0,1,0,0,0], [0,1,0,0,0], [1,0,0,0,0], [1,0,0,0,0], [0,0,0,0,0], 
    [0,0,0,0,0], [0,0,0,0,0], [0,1,0,0,0], [0,1,0,0,0], [0,1,0,0,0], 
    [0,0,0,0,0], [0,0,0,0,0], [1,0,0,0,0], [1,0,0,0,0], [1,0,0,0,0], 
    [1,1,0,0,0], [0,1,0,0,0], [0,1,0,0,0], [0,1,0,0,0]], 
    columns=['entsig', 'exsig','ent', 'in', 'ex']) 

for i in df.index: 
    df['ent'][(df.entsig.shift(1)==1) & (df['ent'].shift(1) == 0) & (df['in'].shift(1) == 0)]=1 
    df['ex'][(df.exsig.shift(1)==1) & (df['in'].shift(1)==1)]=1 
    df['in'][(df.ent.shift(1)==1) | ((df['in'].shift(1)==1) & (df['ex']==0))]=1 

for j in df.index:  
    df['ent'][df['in'] == 1]=0 
    df['in'][df['ex']==1]=0 
    df['ex'][df['ex'].shift(1)==1]=0 

df 

приводит

entsig exsig ent in ex 
0  0  0 0 0 0 
1  1  0 0 0 0 
2  1  0 1 0 0 
3  1  0 0 1 0 
4  0  0 0 1 0 
5  0  1 0 1 0 
6  0  1 0 0 1 
7  1  0 0 0 0 
8  1  0 1 0 0 
9  0  0 0 1 0 
10  0  0 0 1 0 
11  0  0 0 1 0 
12  0  1 0 1 0 
13  0  1 0 0 1 
14  0  1 0 0 0 
15  0  0 0 0 0 
16  0  0 0 0 0 
17  1  0 0 0 0 
18  1  0 1 0 0 
19  1  0 0 1 0 
20  1  1 0 1 0 
21  0  1 0 0 1 
22  0  1 0 0 0 
23  0  1 0 0 0 

Вопрос

  • Как я могу сделать t его код быстрее? Он работает медленно, потому что это цикл, но я не смог придумать решение, которое не использует циклы. Любые идеи или комментарии оценены.
+0

Просто удалите 'for' петли они кажутся избыточными мне – EdChum

+0

Кроме того, вы выполняете то, что известно как цепи индексации, которая может работать на копии, а не просмотреть, см. документы: http: //pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy, в основном вы должны использовать 'ix' или' loc' вместо – EdChum

+0

Если я удалю для циклов ответ будет неправильным. Спасибо за наконечник индексации цепи. – DataByDavid

ответ

0

Если мы можем считать каждую группу 1-х в entsig следует, по крайней мере, один 1 в exsig, то можно вычислить ent, ex и in вроде этого:

def ent_in_ex(df): 
    entsig_mask = (df['entsig'].diff().shift(1) == 1) 
    exsig_mask = (df['exsig'].diff().shift(1) == 1) 
    df.loc[entsig_mask, 'ent'] = 1 
    df.loc[exsig_mask, 'ex'] = 1 
    df['in'] = df['ent'].shift(1).cumsum().subtract(df['ex'].cumsum(), fill_value=0) 
    return df 

Если мы можем сделать это предположение, то ent_in_ex значительно быстрее:

In [5]: %timeit orig(df) 
10 loops, best of 3: 185 ms per loop 

In [6]: %timeit ent_in_ex(df) 
100 loops, best of 3: 2.23 ms per loop 

In [95]: orig(df).equals(ent_in_ex(df)) 
Out[95]: True 

orig, где находится исходный код:

def orig(df): 
    for i in df.index: 
     df['ent'][(df.entsig.shift(1)==1) & (df['ent'].shift(1) == 0) & (df['in'].shift(1) == 0)]=1 
     df['ex'][(df.exsig.shift(1)==1) & (df['in'].shift(1)==1)]=1 
     df['in'][(df.ent.shift(1)==1) | ((df['in'].shift(1)==1) & (df['ex']==0))]=1 

    for j in df.index:  
     df['ent'][df['in'] == 1]=0 
     df['in'][df['ex']==1]=0 
     df['ex'][df['ex'].shift(1)==1]=0 
    return df