Я ищу решения для ускорения функции, которую я написал, чтобы прокрутить фреймворк pandas и сравнить значения столбцов между текущей строкой и предыдущей строкой.
В качестве примера, это упрощенная версия моей проблемы:
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 может увеличить скорость функций, но у меня нет опыта с ним (и я новичок как для pandas, так и для python). Возможно ли передать две строки данных в качестве аргументов функции, а затем использовать Cython для ее ускорения или было бы необходимо создать новые столбцы со значениями "diff
" в них, чтобы функция только считывала и записывала к одной строке кадра данных за раз, чтобы извлечь выгоду из использования Cython? Любые другие быстрые трюки будут очень благодарны!
(Что касается использования .loc, я сравнивал .loc,.iloc и .ix, и этот был немного быстрее, поэтому единственная причина, по которой я сейчас использую)
(Кроме того, мой столбец User
в действительности является unicode not int, что может быть проблематичным для быстрого сравнения)