代码之家  ›  专栏  ›  技术社区  ›  jbet

pandas/numpy/纯python-矢量加法性能

  •  1
  • jbet  · 技术社区  · 4 年前

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

    在python3.6.9、Ubuntu 18.04、numpy=1.18.1、pandas==1.1.3上测试。

    代码

    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
    

    问题

    1. 对于小数组(最多约5k个元素),python比pandas更高效,对于非常小的数组,差异很大。在纯python上,哪些操作比pandas的性能(好得多),有什么一般规则吗?比如“不管你做什么,少于100排的熊猫都会慢一个数量级”?
    2. 据我所知,pandas内部使用numpy。这些性能的不同仅仅是因为pd.Series和np.array之间的转换时间吗?如果是,在创建Series时是否有任何方法强制转换?
    3. (最不重要,但最令人惊讶的是)对于10^6数组,纯python的速度比numpy慢77倍,但对于10^7数组,这一比例仅为33。为什么?
    0 回复  |  直到 4 年前
        1
  •  0
  •   Glauco Reza Hatami    4 年前

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