<address id="9993j"><address id="9993j"><listing id="9993j"></listing></address></address><form id="9993j"><nobr id="9993j"><meter id="9993j"></meter></nobr></form>

    <output id="9993j"><nobr id="9993j"></nobr></output>

    <noframes id="9993j">
        <address id="9993j"><address id="9993j"></address></address>

          <noframes id="9993j"><address id="9993j"><th id="9993j"></th></address>

          <noframes id="9993j">

            <em id="9993j"><form id="9993j"><nobr id="9993j"></nobr></form></em>

            博客專欄

            EEPW首頁 > 博客 > 獨家 | 數據科學家對可復用Python代碼的實用管理方法(附鏈接)

            獨家 | 數據科學家對可復用Python代碼的實用管理方法(附鏈接)

            發布人:數據派THU時間:2021-09-19來源:工程師

            作者:Matthew Mayo, KDnuggets

            翻譯:殷之涵

            校對:歐陽錦

            有很多不同的方法管理自己的代碼,這取決于您的具體要求、個性、技術知識、所扮演角色和諸多其他因素。雖然經驗豐富的開發人員可能有一套非常嚴格的方法可以跨多語言、項目和用例進行代碼管理,但很少編寫自己的代碼的數據分析師由于缺乏必要性,可能會較為疏于代碼管理。其實,在管理代碼這件事情上并沒有對錯之分,這只是一個是否對您自己“有用”和“合適”的問題而已。

            具體來說,我所指的“代碼管理”是指您如何組織、存儲和調用您自己編寫的不同的代碼段——這些代碼段作為您對自己的編程工具箱的長期積累,是很有用的。編程的本質是自動化,因此如果一名編程者發現自己正在重復執行一些類似任務,那么就勢必要考慮以某種方式對該任務的相關代碼進行自動調用。

            這就是我們經常要使用第三方庫的原因。比如要使用支持向量機(SVM)算法時,我們不需要每次都把代碼重新實現一遍;相反,我們可以使用一個庫——也許是 Scikit-learn——這樣我們就能好好利用眾多前人隨著時間推移所不斷完善而成的智慧結晶了。

            除了第三方庫的使用,我們還要把這種“自動化思想”擴展到個人編程領域。您可能已經這樣做了(我希望是的),但如果沒有,以下是我作為一名數據科學家,對自己所寫的可復用 Python 代碼進行管理的幾種固化下來的方法(按照最通用到最不通用來進行排序)。

            自建代碼庫(Full-blown Libraries)

            這是一種最通用的方法,也可以說是最“專業”的方法;然而,這并不意味著它適用于所有的情況。

            如果您發現您在許多用例中都在頻繁使用相同的功能,那么自己搭建一個代碼庫就是正確的選擇。此外,如果您要復用的功能很容易參數化,那這個選擇也十分合理;參數化的意思是,您可以通過編寫和調用帶有變量的通用函數來重復多次地處理任務,每次調用時都可以對變量進行重新定義。

            舉例說明,我經常發現我想在一個字符串中找到某個子字符串第 n 次出現的位置索引,但是并沒有一個現成的Python標準庫函數能支持這一需求。因此,我自己寫了一段簡單的代碼,它接受一個字符串、一個子字符串以及我所求的第n次出現的“n”作為輸入,返回值是字符串中子字符串第n次出現開始的位置索引(具體代碼出處見:

            https://stackoverflow.com/questions/1883980/find-the-nth-occurrence-of-substring-in-a-string)。

            def find_nth(haystack, needle, n):
                start = haystack.find(needle)
                while start >= 0 and n > 1:
                    start = haystack.find(needle, start+len(needle))
                    n -= 1
                return start

            由于我平日有很多文本處理類型的工作,所以我將上述函數連同一些經常使用的其他文本處理函數集合起來并創建了一個庫,這個庫就像其他任何Python 庫一樣被儲存在我的計算機上,并且能夠像其他任何庫一樣進行導入。創建庫的方法雖然不難,但是步驟比較多,所以我就不做過多介紹了,感興趣的讀者可以參考這篇文章:

            https://medium.com/analytics-vidhya/how-to-create-a-python-library-7d5aea80cc3f

            所以現在我有了一個名為textproc的自建代碼庫,我可以隨時輕松地導入和使用我的find_nth函數,再也不用復制并粘貼整段代碼到我編寫的每個要用到它的程序中了。

            from textproc import find_nth
            segment = line[:find_nth(line, ',', 4)].strip()

            此外,如果我想擴展這個庫——即把更多函數添加進去,或者想更改現有的 find_nth函數的代碼,我只需要在底層這一處進行修改后再重新導入即可(而不需要在所有調用之處都進行一次相應的修改)。

            基于特定項目的共享腳本

            有時候并不需要自建代碼庫,因為您想要復用的代碼并沒有當前項目以外的用途,但您確實需要在本項目中對它進行復用。在這種情況下,您可以將這些函數放在一個腳本中,然后簡單地按名稱導入該腳本即可。

            我在讀研究生期間編寫了大量和無監督學習相關的代碼,特別是k-means 聚類。我編寫了用于簇中心初始化、數據點和簇中心之間的距離計算、簇中心重新計算等函數,并使用不同的算法對這些任務進行實現。我很快發現,將其中一些算法函數的副本各自保存在一個單獨的腳本中以供調用并不是最佳選擇,反而將它們先集中在一個腳本中再進行導入會更好?!肮蚕砟_本”這個工作方式與庫幾乎相同,但這個過程是基于特定路徑的,并且僅適用于某一特定項目。

            很快我就積累了不同簇中心初始化函數和距離計算函數的腳本,以及加載和處理數據的函數的腳本。隨著這些代碼變得越來越參數化和具有普適性,它們最終被放到了一個正式的庫中。

            這似乎是事情的常見進展方式,至少根據我的經驗是這樣的:您在腳本中編寫了一個滿足當下使用需要的函數,然后使用它。隨著項目擴展,或者又接手了一個類似項目,您意識到現在使用一個相同的函數會很方便,所以該函數就被放入了一個腳本中以便導入和使用。如果這種用途在短期內繼續發揮作用,并且您發現該函數具有更廣泛和更長期的用途,那么它就會被添加到現有庫中,或者成為一個新庫的基礎組成部分。

            導入簡單腳本這個方法在使用Jupyter Notebook時同樣有用,但在使用方式上有所不同。鑒于Jupyter Notebooks中大部分代碼內容的臨時性、探索性和實驗性,我通常不會把一些notebooks作為模塊導入到其他notebooks中。如果我發現多個notebooks都經常使用某些代碼片段,那我就會把這些代碼片段放入一個單獨腳本中,并存儲在這些notebooks所屬的同一文件夾下,然后將其導入到需要使用它們的notebooks中。這種方法對我來說會更合理一些,同時具有更高的穩定性——相比于特定腳本,notebooks有更高的風險會被重新編輯,難以長期依賴。

            基于特定任務的模板

            我發現我經常重復執行一些相同的任務,而這些任務并不適合參數化,或者參數化的性價比實在很低(需要付出的時間精力遠超所能得到的回報)。在這種情況下,我會把代碼進行模板化,或者標準化(boiler-plating)。比起我在本文開頭所提到的簡單復制粘貼——這些是我在所有情況下都想要避開的工作,模板化的做法顯然要復雜一些,但有時候這卻是正確的選擇。

            例如,我經常需要進行列表化(listify)操作——即使我壓根不清楚待處理的Pandas DataFrame中的內容,仍然需要確定列數和待輸入的列以完成相關函數的編寫,通常還需要對輸出進行調整——上述這些都表明編寫函數的確太耗時了。

            為了應對這種情況,我編寫了一個可靈活更改的腳本模板,并把它放在了一個用于儲存此類模板的專用文件夾中。下面就是listify_df的代碼段,它能把 CSV 文件轉換成Pandas DataFrame,然后再輸出為所需的HTML文件。

            import pandas as pd
            # Read CSV file into dataframe
            csv_file = 'data.csv'
            df = pd.read_csv(csv_file)
            # Iterate over df, creating numbered list entries
            i = 1
            for index, row in df.iterrows():
            entry = '<b>' + str(i) + \
            '. <a href="' + \
            row['url'] + \
            '">' + \
            row['title'] + \
            '</a> + \
            '\n\n<blockquote>\n' + \
            row['description'] + \
            '\n</blockquote>\n'
            i += 1
            print(entry)

            在這個案例中,我們能夠看到清晰的文件名以及對文件夾的有序管理,是很有助于管理這些常用代碼段的。

            單行代碼和短代碼塊

            重復的單行代碼和短代碼塊總是難免出現在我們的日常工作中,為什么不想想辦法做些自動化呢?

            您可以在需要的時候使用文本擴展工具來插入簡短的“短語”。我會用AutoKey來管理這樣的短語,這些短語和一些觸發關鍵字相聯系,一旦輸入這些關鍵字,短語就會自動插入。

            AutoKey

            https://github.com/autokey/autokey

            例如,您在處理特定類型的項目時是否總是需要導入一批相同的庫?您可以通過輸入“#nlpimport”來設置處理特定任務所需的所有導入工作,這一輸入會被識別為觸發關鍵字并被替換為以下內容:

            import sys, requests
            import numpy as np
            import pandas as pd
            import texthero
            import scattertext as st
            import spacy
            from spacy.lang.en.stop_words import STOP_WORDS
            from datasets import load_metric, list_metrics
            from transformers import pipeline
            from fastapi import FastAPI

            需要注意的是,一些 IDE 是具有這種自動插入功能的。我自己通常使用美化的文本編輯器來編寫代碼,所以對于我來說AutoKey是非常必要且有用的。如果您用的是具備此類功能的IDE,那就太好了。關鍵是,您再也不用總是寫一些重復的代碼了。

            以上就是我作為數據科學家對可復用 Python 代碼管理方法的概述。希望它們能對您有所幫助!

            編輯:王菁

            校對:汪雨晴

            *博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。



            關鍵詞: AI

            相關推薦

            技術專區

            關閉
            五月天国产成人AV免费观看
            <address id="9993j"><address id="9993j"><listing id="9993j"></listing></address></address><form id="9993j"><nobr id="9993j"><meter id="9993j"></meter></nobr></form>

              <output id="9993j"><nobr id="9993j"></nobr></output>

              <noframes id="9993j">
                  <address id="9993j"><address id="9993j"></address></address>

                    <noframes id="9993j"><address id="9993j"><th id="9993j"></th></address>

                    <noframes id="9993j">

                      <em id="9993j"><form id="9993j"><nobr id="9993j"></nobr></form></em>