首页 > 解决方案 > 为什么 pandas 的索引这么慢?如何让它更快?

问题描述

运行此代码显示了 pandas 和常规 python 列表之间的速度差异:

ser = pd.Series(range(100))
lst = ser.tolist()

for _ in range(10):
    pandas_time = 0
    list_time = 0
    for _ in range(100000):
        r = randint(0, len(ser)-1)
        t = time()
        ser[r]
        pandas_time += time() - t

        t = time()
        lst[r]
        list_time += time() - t

    print(pandas_time, list_time)

结果(索引随机元素 100000 次的 10 次试验):

Pandas             Regular List
0.6404812335968018 0.03125190734863281
0.6560468673706055 0.0
0.5779874324798584 0.01562190055847168
0.5467743873596191 0.015621662139892578
0.6106545925140381 0.004016399383544922
0.5866603851318359 0.029597759246826172
0.7981059551239014 0.016004562377929688
0.8128316402435303 0.013040542602539062
0.5566465854644775 0.021578073501586914
0.6386256217956543 0.00500178337097168

索引 pandas 系列似乎比 python 列表慢 30 到 100 倍。为什么?我们怎样才能加快速度?

标签: pythonpandas

解决方案


我检查了pandas'源代码。与常规 python 列表相比,pandas 系列中的__getitem__实现有很多额外的业务逻辑,因为 pandas 系列支持使用列表和可迭代的索引。

索引 pandas 系列时,该系列:

  1. 如果密钥可调用,则尝试应用密钥

  2. 获取该键处的索引值(听起来很简单,但请记住,索引是另一个熊猫对象,它还必须支持比常规索引更多的功能)

  3. 检查 2) 是否为标量

  4. 如果是标量返回结果

__getitem__与常规的 python 列表相比,这些额外的步骤大大减慢了速度。

要解决此问题,您可以直接使用底层 numpy 数组。这里我们使用ser.values索引来代替:

ser = pd.Series(range(100))
lst = ser.tolist()

ser = ser.values

for _ in range(10):
    pandas_time = 0
    list_time = 0
    for _ in range(1000000):
        r = randint(0, len(ser)-1)
        t = time()
        ser[r]
        pandas_time += time() - t

        t = time()
        lst[r]
        list_time += time() - t

    print(pandas_time, list_time)

在索引 1000000 个随机元素 10 次后,我们发现 using.values比仅索引 pandas 系列要快得多,但仍然比使用 python 列表慢

pd.Series.values    Regular List
0.18845057487487793 0.04786252975463867
0.10950899124145508 0.11034011840820312
0.048889875411987305 0.09512066841125488
0.17272686958312988 0.1406867504119873
0.14252233505249023 0.048066139221191406
0.06352949142456055 0.07906699180603027
0.1405477523803711 0.07815265655517578
0.18746685981750488 0.08007645606994629
0.1405184268951416 0.0781564712524414
0.07921838760375977 0.1412496566772461

总结.values一下,当您需要快速索引熊猫系列时,使用是一种方法。虽然它看起来.tolist()更快,但请记住,在索引单个元素时它只会稍微快一点。Numpy 数组将支持更快的花式索引,例如使用多个元素进行索引。


推荐阅读