我正在尋找解決方案來加速我寫入的函數,以循環訪問熊貓數據框並比較當前行和前一行之間的列值。在熊貓數據框中比較行和前一行的行數百萬行的最快方法
作爲一個例子,這是我的問題的一個簡化版本:
User Time Col1 newcol1 newcol2 newcol3 newcol4
0 1 6 [cat, dog, goat] 0 0 0 0
1 1 6 [cat, sheep] 0 0 0 0
2 1 12 [sheep, goat] 0 0 0 0
3 2 3 [cat, lion] 0 0 0 0
4 2 5 [fish, goat, lemur] 0 0 0 0
5 3 9 [cat, dog] 0 0 0 0
6 4 4 [dog, goat] 0 0 0 0
7 4 11 [cat] 0 0 0 0
目前,我有一個基於是否該遍歷和「newcol1
」計算值和「newcol2
」的函數' User
'自上一行以來也發生了變化,'Time
'值的差異是否大於1.它還查看存儲在'Col1
'和'Col2
'中的數組中的第一個值,並更新了'newcol3
'和' newcol4
',如果這些值自上一行以來已更改。
下面是我在做什麼目前的僞代碼(因爲我已經簡化了問題,我沒有測試過這一點,但它非常類似於我居然在IPython的筆記本電腦做):
def myJFunc(df):
... #initialize jnum counter
... jnum = 0;
... #loop through each row of dataframe (not including the first/zeroeth)
... for i in range(1,len(df)):
... #has user changed?
... if df.User.loc[i] == df.User.loc[i-1]:
... #has time increased by more than 1 (hour)?
... if abs(df.Time.loc[i]-df.Time.loc[i-1])>1:
... #update new columns
... df['newcol2'].loc[i-1] = 1;
... df['newcol1'].loc[i] = 1;
... #increase jnum
... jnum += 1;
... #has content changed?
... if df.Col1.loc[i][0] != df.Col1.loc[i-1][0]:
... #record this change
... df['newcol4'].loc[i-1] = [df.Col1.loc[i-1][0], df.Col2.loc[i][0]];
... #different user?
... elif df.User.loc[i] != df.User.loc[i-1]:
... #update new columns
... df['newcol1'].loc[i] = 1;
... df['newcol2'].loc[i-1] = 1;
... #store jnum elsewhere (code not included here) and reset jnum
... jnum = 1;
我現在需要將這個函數應用到數百萬行,它不可能很慢,所以我試圖找出加速它的最佳方法。我聽說Cython可以提高函數的速度,但我沒有經驗(我對熊貓和Python都是新手)。是否可以將兩行數據框作爲參數傳遞給函數,然後使用Cython加速它,或者需要創建新的列,其中包含「diff
」值,以便該函數只讀取和寫入一個爲了從使用Cython中受益,每次都要放入一行數據幀?任何其他速度技巧將不勝感激!
(使用的.loc方面,我比較的.loc,.iloc和.IX,這一次是稍快所以這是我使用的是目前的唯一原因)
(另外,我User
在列現實是unicode不是整數,這可能是快速比較的問題)
百萬行,爲什麼不使用Python可以輕鬆連接到的專用數據庫,如MySQL或SQLlite?關係數據庫可以運行復雜的SQL查詢,並通過if/then邏輯對由索引連接的行比較進行比較。它們旨在爲數百萬行進行擴展。即使可以設置觸發器,以便任何用戶更改,可以更新特定的列。 – Parfait 2015-04-04 13:42:49