1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Pandas、Numpy性能優(yōu)化秘籍(全)

        共 5411字,需瀏覽 11分鐘

         ·

        2022-05-14 04:43

        pandas、numpy是Python數(shù)據(jù)科學(xué)中非常常用的庫,numpy是Python的數(shù)值計算擴展,專門用來處理矩陣,它的運算效率比列表更高效。pandas是基于numpy的數(shù)據(jù)處理工具,能更方便的操作大型表格類型的數(shù)據(jù)集。但是,隨著數(shù)據(jù)量的劇增,有時numpy和pandas的速度就成瓶頸。

        如下我們會介紹一些優(yōu)化秘籍:里面包含了 代碼層面的優(yōu)化,以及可以無腦使用的性能優(yōu)化擴展包。

        1、NumExpr

        NumExpr 是一個對NumPy計算式進行的性能優(yōu)化。NumExpr的使用及其簡單,只需要將原來的numpy語句使用雙引號框起來,并使用numexpr中的evaluate方法調(diào)用即可。經(jīng)驗上看,數(shù)據(jù)有上萬條+ 使用NumExpr才比較優(yōu)效果,對于簡單運算使用NumExpr可能會更慢。如下較復(fù)雜計算,速度差不多快了5倍。

        import?numexpr?as?ne

        import?numpy?as?np

        a?=?np.linspace(0,1000,1000)?

        print('#?numpy十次冪計算')
        %timeit?a**10

        print('#?numexpr十次冪計算')
        %timeit?ne.evaluate('a**10')

        2、Numba

        Numba 使用行業(yè)標(biāo)準(zhǔn)的LLVM編譯器庫在運行時將 Python 函數(shù)轉(zhuǎn)換為優(yōu)化的機器代碼。Python 中 Numba 編譯的數(shù)值算法可以接近 C 或 FORTRAN 的速度。

        如果在你的數(shù)據(jù)處理過程涉及到了大量的數(shù)值計算,那么使用numba可以大大加快代碼的運行效率(一般來說,Numba 引擎在處理大量數(shù)據(jù)點 如 1 百萬+ 時表現(xiàn)出色)。numba使用起來也很簡單,因為numba內(nèi)置的函數(shù)本身是個裝飾器,所以只要在自己定義好的函數(shù)前面加個@nb.方法就行,簡單快捷!

        #?pip?install?numba

        import?numba?as?nb

        #?用numba加速的求和函數(shù)
        @nb.jit()
        def?nb_sum(a):
        ????Sum?=?0
        ????for?i?in?range(len(a)):
        ????????Sum?+=?a[i]
        ????return?Sum

        #?沒用numba加速的求和函數(shù)
        def?py_sum(a):
        ????Sum?=?0
        ????for?i?in?range(len(a)):
        ????????Sum?+=?a[i]
        ????return?Sum

        import?numpy?as?np
        a?=?np.linspace(0,1000,1000)?#?創(chuàng)建一個長度為1000的數(shù)組
        print('#?python求和函數(shù)')
        %timeit?sum(a)?
        print('#?沒加速的for循環(huán)求和函數(shù)')
        %timeit?py_sum(a)
        print('#?numba加速的for循環(huán)求和函數(shù)')
        %timeit?nb_sum(a)?
        print('#?numpy求和函數(shù)')
        %timeit?np.sum(a)?

        當(dāng)前示例可以看出,numba甚至比號稱最接近C語言速度運行的numpy還要快5倍+,對于python求和速度快了幾百倍。。

        此外,Numba還支持GPU加速、矢量化加速方法,可以進一步達到更高的性能。

        from?numba?import?cuda
        cuda.select_device(1)

        @cuda.jit
        def?CudaSquare(x):
        ????i,?j?=?cuda.grid(2)
        ????x[i][j]?*=?x[i][j]


        #numba的矢量化加速
        from?math?import?sin
        @nb.vectorize()
        def?nb_vec_sin(a):
        ????return?sin(a)

        3、CuPy

        CuPy 是一個借助 CUDA GPU 庫在英偉達 GPU 上實現(xiàn) Numpy 數(shù)組的庫?;?Numpy 數(shù)組的實現(xiàn),GPU 自身具有的多個 CUDA 核心可以促成更好的并行加速。

        #?pip?install?cupy
        import?numpy?as?np
        import?cupy?as?cp
        import?time

        ###?numpy
        s?=?time.time()
        x_cpu?=?np.ones((1000,1000,1000))
        e?=?time.time()
        print(e?-?s)

        ###?CuPy?
        s?=?time.time()
        x_gpu?=?cp.ones((1000,1000,1000))
        e?=?time.time()
        print(e?-?s)

        上述代碼,Numpy 創(chuàng)建(1000, 1000, 1000)的數(shù)組用了 1.68 秒,而 CuPy 僅用了 0.16 秒,實現(xiàn)了 10.5 倍的加速。隨著數(shù)據(jù)量的猛增,CuPy的性能提升會更為明顯。

        4、pandas使用技巧

        更多pandas性能提升技巧請戳官方文檔:https://pandas.pydata.org/pandas-docs/stable/user_guide/enhancingperf.html

        4.1 按行迭代優(yōu)化

        我們按行對dataframe進行迭代,一般我們會用iterrows這個函數(shù)。在新版的pandas中,提供了一個更快的itertuples函數(shù),如下可以看到速度快了幾十倍。

        import?pandas?as?pd
        import?numpy?as?np
        import?time
        df?=?pd.DataFrame({'a':?np.random.randn(100000),
        ?????????????????????'b':?np.random.randn(100000),
        ????????????????????'N':?np.random.randint(100,?1000,?(100000)),
        ???????????????????'x':??np.random.randint(1,?10,?(100000))})

        %%timeit
        a2=[]
        for?row?in?df.itertuples():
        ????temp=getattr(row,?'a')
        ????a2.append(temp*temp)
        df['a2']=a2
        %%timeit
        a2=[]
        for?index,row?in?df.iterrows():
        ????temp=row['a']
        ????a2.append(temp*temp)
        df['a2']=a2????


        4.2 apply、applymap優(yōu)化

        當(dāng)對于每行執(zhí)行類似的操作時,用循環(huán)逐行處理效率很低。這時可以用apply或applymap搭配函數(shù)操作,其中apply是可用于逐行計算,而applymap可以做更細粒度的逐個元素的計算。

        #?列a、列b逐行進行某一函數(shù)計算
        df['a3']=df.apply(?lambda?row:?row['a']*row['b'],axis=1)
        #?逐個元素保留兩位小數(shù)
        df.applymap(lambda?x:?"%.2f"?%?x)

        4.3 聚合函數(shù)agg優(yōu)化

        對于某列將進行聚合后,使用內(nèi)置的函數(shù)比自定義函數(shù)效率更高,如下示例速度加速3倍

        %timeit??df.groupby("x")['a'].agg(lambda?x:x.sum())

        %timeit??df.groupby("x")['a'].agg(sum)

        %timeit??df.groupby("x")['a'].agg(np.sum)

        4.4 文件操作

        pandas讀取文件,pkl格式的數(shù)據(jù)的讀取速度最快,其次是hdf格式的數(shù)據(jù),再者是讀取csv格式數(shù)據(jù),而xlsx的讀取是比較慢的。但是存取csv有個好處是,這個數(shù)據(jù)格式通用性更好,占用內(nèi)存硬盤資源也比較少。此外,對于大文件,csv還可以對文件分塊、選定某幾列、指定數(shù)據(jù)類型做讀取。

        4.5 pandas.eval

        pandas.eval 是基于第一節(jié)提到的numexpr,pandas也是基于numpy開發(fā)的,numexpr同樣可以被用來對pandas加速)。使用eval表達式的一個經(jīng)驗是數(shù)據(jù)超過 10,000 行的情況下使用會有明顯優(yōu)化效果。

        import?pandas?as?pd?
        nrows,?ncols?=?20000,?100
        df1,?df2,?df3,?df4?=?[pd.DataFrame(np.random.randn(nrows,?ncols))?for?_?in?range(4)]

        print('pd')
        %timeit?df1?+?df2?+?df3?+?df4
        print('pd.eval')
        %timeit?pd.eval("df1?+?df2?+?df3?+?df4")

        5、Cython優(yōu)化

        Cython是一個基于C語言的Python 編譯器,在一些計算量大的程序中,可以Cython來實現(xiàn)相當(dāng)大的加速。考慮大部分人可能都不太了解復(fù)雜的cython語句,下面介紹下Cython的簡易版使用技巧。通過在Ipython加入 Cython 魔術(shù)函數(shù)%load_ext Cython,如下示例就可以加速了一倍。進一步再借助更高級的cython語句,還是可以比Python快個幾十上百倍。

        %%cython
        def?f_plain(x):
        ????return?x?*?(x?-?1)
        def?integrate_f_plain(a,?b,?N):
        ????s?=?0
        ????dx?=?(b?-?a)?/?N
        ????for?i?in?range(N):
        ????????s?+=?f_plain(a?+?i?*?dx)
        ????return?s?*?dx

        6、swifter

        swifter是pandas的插件,可以直接在pandas的數(shù)據(jù)上操作。Swifter的優(yōu)化方法檢驗計算是否可以矢量化或者并行化處理,以提高性能。如常見的apply就可以通過swifter并行處理。

        import?pandas?as?pd
        import?swifter

        df.swifter.apply(lambda?x:?x.sum()?-?x.min())

        7、Modin

        Modin后端使用dask或者ray(dask是類似pandas庫的功能,可以實現(xiàn)并行讀取運行),是個支持分布式運行的類pandas庫,簡單通過更改一行代碼import modin.pandas as pd就可以優(yōu)化 pandas,常用的內(nèi)置的read_csv、concat、apply都有不錯的加速。注:并行處理的開銷會使小數(shù)據(jù)集的處理速度變慢。

        !pip?install?modin
        import?pandas
        import?modin.pandas?as?pd
        import?time

        ##?pandas

        pandas_df?=?pandas.DataFrame({'a':?np.random.randn(10000000),
        ?????????????????????'b':?np.random.randn(10000000),
        ????????????????????'N':?np.random.randint(100,?10000,?(10000000)),
        ???????????????????'x':??np.random.randint(1,?1000,?(10000000))})



        start?=?time.time()

        big_pandas_df?=?pandas.concat([pandas_df?for?_?in?range(25)])

        end?=?time.time()
        pandas_duration?=?end?-?start
        print("Time?to?concat?with?pandas:?{}?seconds".format(round(pandas_duration,?3)))

        ####?modin.pandas
        modin_df?=?pd.DataFrame({'a':?np.random.randn(10000000),
        ?????????????????????'b':?np.random.randn(10000000),
        ????????????????????'N':?np.random.randint(100,?10000,?(10000000)),
        ???????????????????'x':??np.random.randint(1,?1000,?(10000000))})

        start?=?time.time()
        big_modin_df?=?pd.concat([modin_df?for?_?in?range(25)])

        end?=?time.time()
        modin_duration?=?end?-?start
        print("Time?to?concat?with?Modin:?{}?seconds".format(round(modin_duration,?3)))

        print("Modin?is?{}x?faster?than?pandas?at?`concat`!".format(round(pandas_duration?/?modin_duration,?2)))

        - END -

        瀏覽 39
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产呻吟av | 简单AV网 | 99re6国产亚洲这里只有精品 | 五月婷婷五月天 | 亚洲激情在线视频 | 人人草人人射 | 狠狠操人人操 | 亚洲视频在线播放免费 | 久久99久久99精品免观看软件 | 小黄文在线观看 |