2014-06-13 21 views
7

"xpos", "ypos" satırlarında ve sütunlarında ardışık piksel koordinatlarına sahip bir veri çerçevem ​​var ve ardışık pikseller arasındaki her yolun açısını derece olarak hesaplamak istiyorum. Şu anda sunulan çözüm, iyi çalışıyor ve dosya boyutu boyutu yeterince hızlı, ancak tüm satırlar boyunca yinelenen bunu yapmak için pandalar yolu gibi görünüyor. Bir işlevi farklı sütunlara nasıl uygulayacağımı ve işlevleri farklı satır sütunlarına nasıl uygulayacağımı biliyorum, ancak her ikisinin nasıl birleştirileceğini anlayamıyorum. Burada pandalar işlevi birden çok sütun ve birden çok satır için uygular

benim kod:

fix_df = pd.read_csv('fixations_out.csv') 

# wyliczanie kąta sakady 
temp_list=[] 
for count, row in df.iterrows(): 
    x1 = row['xpos'] 
    y1 = row['ypos'] 
    try: 
     x2 = df['xpos'].ix[count-1] 
     y2 = df['ypos'].ix[count-1] 
     a = abs(180/math.pi * math.atan((y2-y1)/(x2-x1))) 
     temp_list.append(a) 
    except KeyError: 
     temp_list.append(np.nan) 

ve sonra

DÜZENLEME df içine geçici listesini ekleyin: Ben yorum yapmaktan ucu uyguladıktan sonra:

df['diff_x'] = df['xpos'].shift() - df['xpos'] 
df['diff_y'] = df['ypos'].shift() - df['ypos'] 

def calc_angle(x): 
    try: 
     a = abs(180/math.pi * math.atan((x.diff_y)/(x.diff_x))) 
     return a 
    except ZeroDivisionError: 
     return 0 

df['angle_degrees'] = df.apply(calc_angle, axis=1) 

Ben karşılaştırıldı Benim df için üç çözüm süresi (df boyutu yaklaşık 6k satırdır), iterasyon uygulanmaktan neredeyse 9 kat daha yavaş ve yaklaşık 1500 kat daha yavaş ildirimde geçerlidir:

yürütme zamanı yineleme ile çözelti, geri df için Yeni bir sütun, insert içerir: yineleme olmadan çözelti 1,51s

çalıştırma süresi ile uygulanır: 0.17s

EdChum tarafından kabul cevabın

yürütme zamanı yineleme olmadan, diff() kullanılarak ve olmaksızın geçerlidir: 0.001s

Öneri: yinelemeyi kullanmak veya uygulamak ve alwa yok Vektörel hesaplamayı kullanmaya çalışırız;) sadece daha hızlı değil, aynı zamanda daha okunabilir.

+1

Başlangıç ​​olarak, farkı "df ['xpos'] olarak hesaplayabilirsiniz.shift() - df ['xpos'] 'yerine bu satır-bilge yapmak yerine, daha sonra tüm sütun üzerinde fonksiyonunuzu kullanarak açı hesaplayabilirsiniz – EdChum

+0

Cevabımı güncelledim 1ms'den daha az performans aldım. büyüklüğü daha hızlı – EdChum

cevap

8

Bunu aşağıdaki yöntemle yapabilirsiniz ve pandaları yolunuza göre karşılaştırdım ve 1000 kat daha hızlıdır, bu da listeyi yeni bir sütun olarak eklemez! önlemek mümkün apply kullanarak bu sıra sıra faaliyet olarak her zaman daha sonra tüm dizinin veya dataframe üzerinde çalışmak bu tercih bir vektörleştirilmiş yöntem bulabilirse Bu, bir 10000 satır dataframe Ayrıca

In [108]: 

%%timeit 
import numpy as np 
df['angle'] = np.abs(180/math.pi * np.arctan(df['xpos'].shift() - df['xpos']/df['ypos'].shift() - df['ypos'])) 

1000 loops, best of 3: 1.27 ms per loop 

In [100]: 

%%timeit 
temp_list=[] 
for count, row in df.iterrows(): 
    x1 = row['xpos'] 
    y1 = row['ypos'] 
    try: 
     x2 = df['xpos'].ix[count-1] 
     y2 = df['ypos'].ix[count-1] 
     a = abs(180/math.pi * math.atan((y2-y1)/(x2-x1))) 
     temp_list.append(a) 
    except KeyError: 
     temp_list.append(np.nan) 
1 loops, best of 3: 1.29 s per loop 

üzerinde yapıldı.

GÜNCELLEME

sadece bu daha da hızlı kod ile sonuçlanan bu diff için yönteminde orada inşa edilmiştir önceki satırdan bir çıkarma yapıyoruz görünce:

In [117]: 

%%timeit 
import numpy as np 
df['angle'] = np.abs(180/math.pi * np.arctan(df['xpos'].diff(1)/df['ypos'].diff(1))) 

1000 loops, best of 3: 1.01 ms per loop 

Diğer bir güncelleme

Seri ve veri bölümü için bir yöntem oluşturma yöntemi de var, bu artık daha fazla zaman ayırıyor ve su elde ediyorum b 1ms zaman:

In [9]: 

%%timeit 
import numpy as np 
df['angle'] = np.abs(180/math.pi * np.arctan(df['xpos'].diff(1).div(df['ypos'].diff(1)))) 

1000 loops, best of 3: 951 µs per loop 
+0

'abs' ilk durumda' np.abs' olmalıdır? – joris

+0

@joris, tutarlılık için evet ama 1.29 ms karşı 1.27ms çok az fark yaptı, yine de cevabı güncelleyeceğim, teşekkürler – EdChum

İlgili konular