Python 为什么熊猫是';这么慢?如何使它更快?

Python 为什么熊猫是';这么慢?如何使它更快?,python,pandas,Python,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

运行此代码显示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)
结果(10次索引随机元素100000次的试验):


熊猫系列的索引速度似乎比python列表慢30-100倍。为什么?如何加快速度?

我查看了
pandas'
源代码。与常规python列表相比,pandas系列中的
\uuuuu getitem\uuuu
实现有许多额外的业务逻辑,因为pandas系列支持使用列表和iterables进行索引

为熊猫系列编制索引时,请选择以下系列:

  • 尝试应用可调用的密钥

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

  • 检查2)是否为标量

  • 如果是标量,则返回结果

  • 与常规python列表相比,这些额外的步骤大大降低了
    \uuuu getitem\uuu
    的速度

    要解决这个问题,您可以直接使用底层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次之后,我们发现使用
    .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数组将支持更快的奇特索引,比如使用多个元素进行索引。

    我查看了
    pandas'
    源代码。与常规python列表相比,pandas系列中的
    \uuuuu getitem\uuuu
    实现有许多额外的业务逻辑,因为pandas系列支持使用列表和iterables进行索引

    为熊猫系列编制索引时,请选择以下系列:

  • 尝试应用可调用的密钥

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

  • 检查2)是否为标量

  • 如果是标量,则返回结果

  • 与常规python列表相比,这些额外的步骤大大降低了
    \uuuu getitem\uuu
    的速度

    要解决这个问题,您可以直接使用底层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次之后,我们发现使用
    .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数组将支持更快的花式索引,如使用多个元素进行索引。

    pandas对索引和重新索引的实现质量较低。 它包含太多的开销

    请参阅以下链接以了解进一步的讨论。

    熊猫指数和重新指数的实施质量低下。 它包含太多的开销

    请参阅以下链接以了解进一步的讨论。

    因为pandas经过优化,可以以矢量化的方式索引多个值,而不是像列表一样索引单个值。它还支持索引对齐,这通常非常有用,但与仅numpy相比增加了大量开销。因为pandas优化为以矢量化方式索引许多值,而不是像列表那样索引单个值。它还支持索引对齐,这通常非常有用,但与简单的numpy相比,它增加了大量开销。