Pandas性能问题-需要帮助优化

5

我写了一些使用pandas库的Python代码。但是,这段代码似乎有点慢,所以我通过cProfile运行它,以查看瓶颈在哪里。 根据cProfile结果之一,瓶颈在于对pandas.lib_scalar_compare的调用。

1604  262.301    0.164  262.301    0.164 {pandas.lib.scalar_compare}

我的问题是 - 在什么情况下会调用这个函数?我猜测当我选择 DataFrame 的一部分时会调用它。以下是我的代码示例:
if (var=='9999'):
    dataTable=resultTable.ix[(resultTable['col1'] == var1)  
                                             & (resultTable['col2']==var2)].copy() 
else:
    dataTable=resultTable.ix[(resultTable['col1'] == var1)  
                                           & (resultTable['col2']==var2)
                                           & (resultTable['col3']==int(val3))].copy() 

我有以下问题:
  1. 这是最终导致瓶颈的代码片段吗?
  2. 如果是的话,有没有优化的方法? 我目前使用的pandas版本是pandas-0.8
非常感谢您的帮助。

在这种情况下,.copy() 没有任何作用,省略它会稍微加快速度。想必这不是你的整个代码... - Andy Hayden
我不确定你的数据框有多大,但是你可以对ResultTable进行unstack操作,并使用multiindex元组来访问它。 - Zelazny7
2个回答

6

我的代码在pandas.lib.scalar_compare中花费了大量时间,通过将基于字符串的列的数据类型转换为“category”,我能够将速度提高10倍。

例如:

   $ df['ResourceName'] = df['ResourceName'].astype('category')

更多信息请参见https://pandas.pydata.org/pandas-docs/stable/user_guide/categorical.html

这个链接提供了有关Pandas中分类数据类型的详细信息。

谢谢,链接不起作用,但我成功将代码执行时间缩短了20倍!!! - otmezger
1
我认为文档已经移动到这里:https://pandas.pydata.org/pandas-docs/stable/user_guide/categorical.html - Guido van Rossum

1
您可以使用列 col1-col3 来设置索引。以下是一个玩具示例:
In [1]: df = DataFrame(np.arange(20).reshape(5,4))

In [2]: df
Out[2]:
    0   1   2   3
0   0   1   2   3
1   4   5   6   7
2   8   9  10  11
3  12  13  14  15
4  16  17  18  19

In [3]: df2 = df.set_index(keys=[0,1,2])

In [4]: df2
Out[4]:
           3
0  1  2
0  1  2    3
4  5  6    7
8  9  10  11
12 13 14  15
16 17 18  19

多级索引元组:
In [5]: %timeit df2.ix[(4,5,6)]
10000 loops, best of 3: 99.5 us per loop

原始数据框:

In [6]: %timeit df.ix[(df[0]==4) & (df[1]==5) & (df[2]==6)][3]
1000 loops, best of 3: 515 us per loop

更新:解决重复索引

In [1]: df = DataFrame(np.arange(20).reshape(5,4))

In [2]: df = concat([df, df])

In [3]: df
Out[3]:
    0   1   2   3
0   0   1   2   3
1   4   5   6   7
2   8   9  10  11
3  12  13  14  15
4  16  17  18  19
0   0   1   2   3
1   4   5   6   7
2   8   9  10  11
3  12  13  14  15
4  16  17  18  19

这个失败了:
In [4]: df2 = df.set_index(keys=[0,1,2])

In [5]: df2.ix[(0,1,2)]

KeyError: u'no item named 1'

这个可以工作:

In [6]: df2 = df.set_index(keys=[0,1,2]).sort()

In [7]: df2.ix[(0,1,2)]
Out[7]:
       3
0 1 2
0 1 2  3
    2  3

我有点惊讶这个速度这么快,但我想我不应该感到惊讶... :) - Andy Hayden
MultiIndex方法只能作为唯一索引使用 - 如果我只想选择符合某个条件的一堆行,我必须使用布尔方法。谢谢 - femibyte
如果你对数据框进行排序,这个方法就会起作用。请查看我的编辑回复。 - Zelazny7

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接