2

我有一个Python 脚本,它会收集一些奇怪的日志文件并将它们放入 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's 是短路和所有......但是可能有更好的方法吗?

否则,我还能做些什么来帮助它运行得更快吗?生成的 DataFrame 应该很好地适合 RAM,但我不知道是否应该设置一些东西来确保缓存等是最佳的。谢谢大家!

4

1 回答 1

2

像这样迭代和查找非常慢(即使它会短路),很可能速度取决于它击中s的可能性......

一种更“numpy”的方法是对整个数组进行此计算:

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()

如果速度至关重要,并且短路很重要,那么在 cython 中重写您的函数可能是一个想法,您可以在其中快速迭代numpy 数组。

于 2013-07-23T20:05:22.570 回答