【问题标题】:Why are simple operations on pandas.DataFrames so slow compared to the same operations on numpy.ndarrays?为什么 pandas.DataFrames 上的简单操作比 numpy.ndarrays 上的相同操作慢?
【发布时间】:2020-09-14 13:22:21
【问题描述】:

为什么pandas.DataFrames 上的操作这么慢?!请看以下示例。

测量:

  • 创建一个填充了随机浮点数的numpy.ndarray
  • 创建一个 pandas.DataFrame 填充相同的 numpy 数组

我测量以下操作的时间

  1. 对于numpy.ndarray

    • 沿 0 轴取和
    • 沿 1 轴求和
  2. 对于pandas.DataFrame

    • 沿 0 轴取和
    • 沿 1 轴求和
  3. 对于pandas.DataFrame.values -> np.ndarray

    • 沿 0 轴取和
    • 沿 1 轴求和

观察

  • 总结numpy.ndarrays' is much faster then operating onpandas.DataFrames`。
  • 如果pd.DataFrame 不只包含浮点数并且没有附加任何特殊内容(MultiIndex 或其他),这甚至是正确的。
  • numpy.ndarray 上的操作大约快 7 到 10 倍。

问题

  1. 为什么会这样?
  2. 如何优化?
  3. pandas 是否无法调用或通过numpys 的操作?
import numpy as np
import pandas as pd

n = 50000
m = 5000
array = np.random.uniform(0, 1, (n, m))
dataframe = pd.DataFrame(array)

麻木

%%timeit
array.sum(axis=0)
206 ms ± 3.78 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%%timeit
array.sum(axis=1)
233 ms ± 33.9 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

熊猫

%%timeit
dataframe.sum(axis=0)
1.65 s ± 14.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%%timeit
dataframe.sum(axis=1)
1.74 s ± 15.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

没有熊猫的熊猫

让我们单独对值进行操作...

%%timeit
dataframe.values.sum(axis=0)
206 ms ± 7.13 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%%timeit
dataframe.values.sum(axis=1)
181 ms ± 1.66 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

【问题讨论】:

  • Sofia Heisler from pycon2017 states 和 Pandas 一样,NumPy 对数组对象(简称 ndarrays)进行操作;但是,它省去了 Pandas 系列操作所产生的大量开销,例如索引、数据类型检查等。因此,NumPy 数组的操作可以比 Pandas 系列的操作快得多。跨度>
  • @Sofia:谢谢您的回答,但如果数据框如此简单,为什么要这样做?它没有混合数据类型。我希望,在这种情况下,我只会得到一些开销,这些开销会随着更大的矩阵而缩小。

标签: python pandas numpy dataframe


【解决方案1】:

Pandas 使用 numpy 作为其底层数据容器,但提供了更多功能。 DataFrame 包含可能具有不同 dtype 的一维 numpy 数组的集合,以及 2 个索引(一个用于行,一个用于列)。这些索引甚至可以是 MultiIndex 类型。

所有这些都是以性能为代价的。

好消息是,如果您不需要对 pandas 进行花哨的索引,您可以直接在 numpy 级别处理底层 numpy 数组以获得额外的性能。

【讨论】:

  • 亲爱的 Serge,我认为你说的不是真的,pandas(至少对于 0.23.4 版本)不会将数据存储在 1d numpy 数组的集合中。对于给定的数据类型(如 float64),数据始终是 2d(块)。还是我错了?我使用 pandas 尤其是因为它的 MultiIndex 和它对一些多维建模的分组能力。虽然 pandas 在分组和聚合方面非常慢,但您可以对其进行调整,例如参见 stackoverflow.com/questions/56274882/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-20
  • 2012-02-09
  • 2018-05-22
  • 2016-09-20
  • 1970-01-01
  • 2018-03-24
相关资源
最近更新 更多