【问题标题】:pandas performance issue - need help to optimize熊猫性能问题 - 需要帮助优化
【发布时间】:2021-01-30 06:33:22
【问题描述】:

我编写了一些 Python 代码,大量使用了 pandas 库。代码似乎有点慢,所以我通过 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. 是sn-p代码最终调用了导致瓶颈的代码吗?
  2. 如果是这样,是否有任何优化? 我目前使用的 pandas 版本是 pandas-0.8

对此的任何帮助将不胜感激。

【问题讨论】:

  • .copy() 在这种情况下不做任何事情,不这样做会加快速度略微。大概这不是你的全部代码......
  • 我不确定您的数据框有多大,但您可以取消堆叠 ResultTable 并使用多索引元组访问它

标签: python pandas


【解决方案1】:

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

例如:

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

欲了解更多信息,请参阅https://pandas.pydata.org/pandas-docs/stable/user_guide/categorical.html

【讨论】:

【解决方案2】:

您可以使用列 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

【讨论】:

  • 我有点惊讶这速度这么快,但我想我不应该...... :)
  • MultiIndex 方法仅用作唯一索引 - 如果我只想选择一堆满足某个标准的行,我必须使用布尔方法。谢谢
  • 如果您对数据框进行排序,这将起作用。查看我编辑的回复。
猜你喜欢
  • 2023-02-25
  • 1970-01-01
  • 2012-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多