我正在寻找解决方案来加速我写入的函数,以循环访问熊猫数据框并比较当前行和前一行之间的列值。在熊猫数据框中比较行和前一行的行数百万行的最快方法
作为一个例子,这是我的问题的一个简化版本:
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