我有一个Python script,它正在制作一些奇怪的日志文件并将它们放入pandas.DataFrame中,这样我就可以进行一些统计分析。由于日志是5分钟间隔的进程快照,当我读取每个文件时,我正在检查新行与最后一个文件输入的数据,看看它们是否是之前的相同进程(在这种情况下,我只是更新了在现有记录上的时间)。它工作正常,但当单个日志超过100,000行时可能会出乎意料地慢。
当我分析性能时,几乎没有突出,但它确实显示了在这个简单函数上花费了大量时间,这基本上是将一系列与前一个日志中携带的行进行比较:
def carryover(s,df,ids):
# see if pd.Series (s) matches any rows in pd.DataFrame (df) from the given indices (ids)
for id in ids:
r = df.iloc[id]
if (r['a']==s['a'] and
r['b']==s['b'] and
r['c']==s['c'] and
r['d']==s['d'] and
r['e']==s['e'] and
r['f']==s['f'] ):
return id
return None
我认为这是非常有效的,因为and
是短路的而且所有......但是可能有更好的方法吗?
否则,我还能做些什么来帮助它更快地运行吗?生成的DataFrame应该适合RAM,但我不知道是否应该设置一些东西以确保缓存等是最佳的。谢谢,全部!
答案 0 :(得分:2)
这样迭代和查找速度相当慢(即使它会短路),很可能速度取决于击中s的可能性......
更“笨拙”的方法是对整个阵列进行计算:
equals_s = df.loc[ids, ['a', 'b', 'c', 'd', 'e', 'f']] == s.loc['a', 'b', 'c', 'd', 'e', 'f']
row_equals_s = equals_s.all(axis=1)
然后,第一个为True的索引是idxmax
:
row_equals_s.idxmax()
如果速度至关重要,而且短路很重要,那么rewrite your function in cython就可以了,你可以在numpy数组上迭代快速。