我正在寻找加速一个函数的解决方案,该函数循环遍历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都很陌生)。是否可能将一个dataframe的两行作为参数传递给该函数,然后使用Cython加速它,或者需要创建带有“diff
”值的新列,以便函数一次只读取并写入一个dataframe中的一行,从而受益于使用Cython?任何其他加速技巧都将不胜感激!
(关于使用.loc,我比较了.loc、.iloc和.ix,发现.loc稍微快一些,所以目前我只使用这个)
(另外,我的“User”列实际上是unicode而不是int,这可能会对速度产生问题)