【问题标题】:Python - performance issue -- filter pandas dataframe versus filter list of dics vs numpy recsPython - 性能问题 - 过滤 pandas 数据帧与过滤器列表的 dics 与 numpy recs
【发布时间】:2013-08-14 14:32:12
【问题描述】:

我是 Python 新手,对 pandas 也很陌生。

我想使用它,但是将两个 cols 的 pandas 过滤与字典列表(均为 80 行)进行比较,它似乎有巨大的性能差异。我最大的问题是为什么 pandas 需要这么长时间才能运行。

熊猫数据框

timeit a = dfEnts[(dfEnts["col"]=="ro") & (dfEnts["sty"]=="hz")]

1000 次循环,最好的 3 次:239 us 每个循环

vs 简单的 dics 列表

timeit b = [ix for ix,ent in enumerate(ents) if (ent['col']=="ro") & (ent["sty"]=="hz")]

100000 次循环,最好的 3 次:11.4 us 每个循环

vs numpy 结构化/记录数组

timeit a = entsRec[(entsRec["col"]=="ro") & (entsRec["sty"]=="hz")]

100000 次循环,3 次取胜:18.2 us 每个循环

还有其他使用 pandas 但响应时间相似的好方法吗?


脚本是这样的..

ents = []

for idx in xrange(0,80)

    dic = {'n':f, 'p':props,'li':li,'col':col,'sty':sty,'nu':nu,'ge':ge,'rr':rr,'ssty':ssty} 
    ents.append(dic)

# DataFrame
dfEnts = pd.DataFrame(ents)

# np rec array
entsTuples = [(ent[ 'n'],ent['p'], ent[ 'li'],ent['col'], ent[ 'sty'], ent['nu'],ent['ge'],ent[ 'rr'], ent['ssty']) for ent in ents]
ents_dt = dtype([('n', 'O'), ('p', 'O'), ('li', 'i1'), ('col', 'O'), ('sty', 'O'), ('nu', 'i1'), ('ge', 'i1'), ('rr', 'i1'), ('ssty', '<i4')])
entsRec = np.array(entsTuples,ents_dt)

然后我计时。


【问题讨论】:

  • 您能否附上您的数据文件并在创建dfEntsents 结构的地方添加一段代码? ents 在我看来更像是一个列表而不是字典。
  • 这只是显示了一个小的函数调用开销;用 10000 个元素试试这个
  • thx 4 您的评论.. 抱歉,是的,是 dics 列表。无论如何,dataFrame 性能是我关心的问题,因为我可以理解这种性能......我做错了什么?谢谢
  • 杰夫,您是说熊猫仅在最少的记录/行数之上表现良好。这是在某处记录的限制吗?谢谢
  • 维克托有一个很好的例子;有时,对于一个很小的数据集,事物会具有不同的性能特征。耗时小于 1 毫秒的操作很难优化(而且不值得花时间这样做,除非它们被多次调用)。如果是这种情况,那么您应该改变处理问题的方式。

标签: python performance pandas


【解决方案1】:

当您处理小型数据集时,列表可能对性能有一点好处,因为列表推导和字典查找在 Python 中进行了非常优化。但这通常是微不足道的差异。一旦您尝试使用更大的数据集,您会发现更大的差异并开始感受到 pandas 库提供的好处。

ents = []
for i in xrange(0, 10000000):
    dic = {
        'n': i, 'p': i, 'li': i, 'col': i, 'sty': i,
        'nu': i, 'ge': i, 'rr': i, 'ssty': i
    } 
    ents.append(dic)
dfEnts = pd.DataFrame(ents)

%%timeit
a = dfEnts[(dfEnts["col"] == 44) & (dfEnts["sty"]== 44)]
10 loops, best of 3: 96.1 ms per loop

%%timeit
b = [ix for ix,ent in enumerate(ents) if (ent['col'] == 44) & (ent["sty"] == 44)]
1 loops, best of 3: 1.68 s per loop

此外,pandas DataFrame 提供的功能比字典列表多得多,所以我认为它们甚至没有可比性。

【讨论】:

  • 谢谢,所以最后我们说我不应该将 pandas 用于小数据记录.. numpy 表现得很好......而且我一直认为 pandas 很聪明np的抽象。不过我错了。
  • pandas NumPy 的智能抽象。它在底层使用 NumPy 数组。 NumPy 的行为方式与本示例中 pandas 的行为方式相同。在这个例子中,你使用了 python 列表而不是 NumPy 数组。
  • 抱歉,我错过了那部分。结构化/记录数组本身就是一头野兽:)。它们是一个连续的内存块,因此 NumPy 能够执行 pandas 无法执行的一些优化,因为它的设计目的略有不同。
猜你喜欢
  • 1970-01-01
  • 2011-05-01
  • 1970-01-01
  • 2022-11-10
  • 1970-01-01
  • 2021-07-11
  • 2019-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多