pandas/numpy/pure-python-向量加法性能

pandas/numpy/pure-python-向量加法性能,python,pandas,performance,numpy,Python,Pandas,Performance,Numpy,我比较了在pandas/numpy/pure python中添加两个向量所需的时间,得到了一些(对我来说)令人惊讶的结果 在python3.6.9、ubuntu18.04、numpy=1.18.1、pandas=1.1.3上测试 代码 结果 问题 对于小数组(最多5k个元素),python比pandas更有效,对于非常小的数组,差别很大。在纯python上,哪些操作的性能(如此之多)优于pandas,这有什么一般规则吗?比如“对于少于100排的熊猫,无论你做什么,它们都会慢一个数量级” 据我所知

我比较了在
pandas
/
numpy
/pure python中添加两个向量所需的时间,得到了一些(对我来说)令人惊讶的结果

在python3.6.9、ubuntu18.04、numpy=1.18.1、pandas=1.1.3上测试

代码 结果 问题
  • 对于小数组(最多5k个元素),python比pandas更有效,对于非常小的数组,差别很大。在纯python上,哪些操作的性能(如此之多)优于pandas,这有什么一般规则吗?比如“对于少于100排的熊猫,无论你做什么,它们都会慢一个数量级”
  • 据我所知,熊猫内部使用numpy。这些性能是否仅仅因为pd.系列和np.阵列之间的转换时间不同?如果是,是否有任何方法在创建序列时强制转换
  • (最不重要,但最令人惊讶的是)对于10^6数组,纯python的速度大约是numpy的77倍,但是对于10^7,这个比率只有33倍。为什么?

  • 无论如何,这段代码可以用矢量算法编写,在这种情况下,numpy将为您提供超过1000>的加速,用于处理大量数据。

    没有什么太令人惊讶的
    numpy
    最快(从阵列开始时)。对于超大阵列,由于内存管理的复杂性,相对性能会下降
    pandas
    使用numpy数组,但增加了跟踪行索引的开销(可能更多)。
    import pandas as pd                                                             
    import numpy as np                                                              
    import random                                                                   
    from timeit import timeit                                                       
                                                                                    
    repeat = 1000                                                                   
    max_exp =7                                                                      
                                                                                    
    def time_all(a, b):                                                             
        sa = pd.Series(a)                                                           
        sb = pd.Series(b)                                                           
                                                                                    
        na = np.array(a)                                                            
        nb = np.array(b)                                                            
                                                                                    
        py_sum = lambda: [x + y for x, y in zip(a, b)]                              
        pd_sum = lambda: sa + sb                                                    
        np_sum = lambda: na + nb                                                    
                                                                                    
        py_time = timeit(py_sum, number=repeat)                                     
        pd_time = timeit(pd_sum, number=repeat)                                     
        np_time = timeit(np_sum, number=repeat)                                     
                                                                                    
        return py_time, pd_time, np_time                                            
                                                                                    
    for i in range(2, max_exp):                                                     
        size = 10 ** i                                                              
                                                                                    
        a = [random.randint(0, 100) for x in range(0, size)]                        
        b = [random.randint(0, 100) for x in range(0, size)]                        
                                                                                    
        py_time, pd_time, np_time = time_all(a, b)                                  
        py_pd = round(py_time / pd_time, 4)                                         
        py_np = round(py_time / np_time, 4)                                         
        pd_np = round(pd_time / np_time, 4)    
                                         
        print('''                                                                   
    ARRAY SIZE: {}                                                                  
        PY/PD: {}                                                                   
        PY/NP: {}                                                                   
        PD/NP: {}'''.format(size, py_pd, py_np, pd_np)) 
    
    ARRAY SIZE: 100
        PY/PD: 0.0357
        PY/NP: 8.656
        PD/NP: 242.1978
    
    ARRAY SIZE: 1000
        PY/PD: 0.3286
        PY/NP: 44.3758
        PD/NP: 135.05
    
    ARRAY SIZE: 10000
        PY/PD: 2.8774
        PY/NP: 69.2828
        PD/NP: 24.0785
    
    ARRAY SIZE: 100000
        PY/PD: 11.7784
        PY/NP: 76.5296
        PD/NP: 6.4974
    
    ARRAY SIZE: 1000000
        PY/PD: 26.2985
        PY/NP: 33.1973
        PD/NP: 1.2623