2017-02-05 19 views
5

Geçerli kod oldukça yavaş (ve Python en iyi uygulamaları öğrenmek istiyorum) olarak aşağıdaki kodu vektörsel bir şekilde yazmak istiyorum. Temel olarak, kod bugünün değeri dünün değerinin% 10'u içinde kalıyorsa, bugünün değeri (yeni bir sütunda) dünün değeriyle aynıdır. Aksi takdirde, bugünkü değeri değişmedi:Döngüler kullanmak yerine kod nasıl vektörel bir şekilde yazılır?

OldCol NewCol 
0  100  100 
1  115  115 
2  101  101 
3  100  101 
4  99  101 
5  70  70 
6  72  70 
7  75  70 
8  78  70 
9  80  70 
10  110  110 

sen yardım edebilir:

def test(df): 
    df['OldCol']=(100,115,101,100,99,70,72,75,78,80,110) 
    df['NewCol']=df['OldCol'] 
    for i in range(1,len(df)-1): 
     if df['OldCol'][i]/df['OldCol'][i-1]>0.9 and df['OldCol'][i]/df['OldCol'][i-1]<1.1: 
      df['NewCol'][i]=df['NewCol'][i-1] 
     else: 
      df['NewCol'][i]=df['OldCol'][i] 
    return df['NewCol'] 

çıktı şu olmalıdır?

Böyle bir şey kullanmak istiyorum ama benim sorunu çözmek başaramadı: NewCol olduğu

df[(0.9 <= df['NewCol']/df['OldCol']) & (df['NewCol']/df['OldCol'] <= 1.1)] size tüm satırları verecek:

def test(df): 
    df['NewCol']=df['OldCol'] 
    cond=np.where((df['OldCol'].shift(1)/df['OldCol']>0.9) & (df['OldCol'].shift(1)/df['OldCol']<1.1)) 
    df['NewCol'][cond[0]]=df['NewCol'][cond[0]-1]  
    return df  
+1

'df' bir veri çerçevesi doğru: bir paralel olarak

? Df ['OldCol'] 'veya' NewCol '' dtype' nedir? Sanırım bu Pythonic'ten daha iyi bir panda kodlama sorunu. – hpaulj

+0

'' OldCol = (100,115,101,100,99,70,72,75,78,80,81,82,110) '' için istenen sonuç nedir? – wwii

cevap

0

Orijinal dataframe maske boolean gerekir OldCol

% 10'u dahilinde Yani bu satırlarda NewCol alanını ayarlamak için:

within_10 = df[(0.9 <= df['NewCol']/df['OldCol']) & (df['NewCol']/df['OldCol'] <= 1.1)] 
within_10['NewCol'] = within_10['OldCol'] 
0

"Atlama" günlerini bulmanın iyi bir yolu gibi göründüğünden, sadece trickier bitini göstereceğim. Bu nedenle, old uzunluğuna sahip N ve aynı boyutta bir boolean numpy dizisi jump olan bir sayı diziniz olduğunu varsayalım. Konvansiyonel olarak jump'un sıfır elemanı True'da ayarlanır. Sonra ilk ayakları arasındaki tekrarların sayıları hesaplayabilir: Bu bir kez sen np.repeat kullanabilirsiniz

jump_indices = np.where(jumps)[0] 
repeats = np.diff(np.r_[jump_indices, [N]]) 

:

new = np.repeat(old[jump_indices], repeats) 
2

üç adımda bir çözüm: For

df['variation']=(df.OldCol/df.OldCol.shift()) 
df['gap']=~df.variation.between(0.9,1.1) 
df['NewCol']=df.OldCol.where(df.gap).fillna(method='ffill') 

:

OldCol variation gap NewCol 
0  100  nan True  100 
1  115  1.15 True  115 
2  101  0.88 True  101 
3  100  0.99 False  101 
4  99  0.99 False  101 
5  70  0.71 True  70 
6  72  1.03 False  70 
7  75  1.04 False  70 
8  78  1.04 False  70 
9  80  1.03 False  70 
10  110  1.38 True  110 

Bu örnekte döngülerden 30 kat daha hızlı görünüyor.

x=df.OldCol;df['NewCol']=x.where(~(x/x.shift()).between(0.9,1.1)).fillna(method='ffill') 
+0

Bu tam olarak ihtiyacım olan şey - Teşekkürler – crazyfrog

İlgili konular