我正在寻找解决方案来加速我编写的函数,以循环遍历 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
' and 'newcol2
'基于是否'User
' 自上一行以来发生了变化,并且 ' 中的差异是否存在Time
' 值大于 1。它还会查看存储在 ' 中的数组中的第一个值Col1
' and 'Col2
'和更新'newcol3
' and '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 而不是 int,这对于快速比较可能会出现问题)