使用Python時常見的9個錯誤

千鋒IT教育發表於2022-10-26

透過應用軟體工程最佳實踐,可以交付質量更好資料科學的專案。更好的質量可能是更少的錯誤、可靠的結果和更高的編碼效率。

最佳實踐都是從錯誤中總結出來的,所以這裡我們總結了一些遇到的最常見的錯誤,並提供瞭如何最好地解決這些錯誤的方法、想法和資源。

1、不使用虛擬環境

這本身不是編碼問題,但我仍然認為每種型別的專案進行環境的隔離是一個非常好的實踐。

為什麼要為每個專案使用專用環境呢?

第一個原因是Python本身包管理的問題,我們想盡量減少包和版本之間的衝突。

另外一個原因是我們程式碼和依賴可以方便的部署到任意的位置

使用虛擬環境可以從Anaconda 或 Pipenv 開始。如果想更深入那麼 Docker 是首選。

2、過度使用Jupyter Notebooks

Notebooks 非常適合用於教育目的和做一些快速而複雜的分析工作,但它不能作為一個好的 IDE。

一個好的 IDE 是應對資料科學任務時的真正武器,可以極大地提高您的工作效率。

Notebooks 很適合做實驗,而且可以輕鬆地將結果展示給其他人。但是它很容易出錯,當涉及到執行長期、協作和可部署的專案時,最好還是使用IDE,例如 VScode、Pycharm、Spyder 等。

3、使用絕對而不是相對路徑

絕對路徑的最大問題是無法進行方便部署,解決這個問題的主要方法是將工作目錄設定為專案根目錄,並且不要再專案中包含專案目錄外的檔案,並且在程式碼中的所有路徑均使用相對路徑。

 import pandas as pd
 import numpy as np
 import os
 #### 錯誤的方式 #####
 excel_path1 = "C:\\Users\\abdelilah\\Desktop\\mysheet1.xlsx"
 excel_path2 = "C:\\Users\\abdelilah\\Desktop\\mysheet2.xlsx"
 mydf1 = pd.read_excel(excel_path1)
 mydf2 = pd.read_excel(excel_path2)
 
 #### 正確的方式 ####
 DATA_DIR = "data"
 #將要讀取的檔案複製到data目錄
 crime06_filename = "CrimeOneYearofData_2006.xlsx"
 crime07_filename = "CrimeOneYearofData_2007.xlsx"
 crime06_df = pd.read_excel(os.path.join(DATA_DIR, crime06_filename))
 crime07_df = pd.read_excel(os.path.join(DATA_DIR, crime07_filename))

4、不處理警告

當我們的程式碼能夠執行但產生奇怪的警告訊息,我們很高興終於讓程式碼執行並收到了有意義的輸出。但是我們需要處理這些警告嗎?

首先,警告本身並不是錯誤,但它們是會引起我們對潛在錯誤或問題的提示。當你的程式碼中能夠執行成功但可能不是它的預期方式時,警告就會出現。

我遇到的最常見的警告是 Pandas 的“SettingwithCopyWarning”和“DeprecationWarning”。

SettingwithCopyWarning最大的原因是 Pandas 檢測到鏈式賦值(Chained Assignment)時發生的警告,我們應該避免對鏈式索引的結果賦值,因為這個操作有可能會報warning也有可能不會報。

DeprecationWarning 通常指出 Pandas 棄用了某些功能,並且您的程式碼在使用更高版本時會中斷。

這裡的建議並不是要處理所有的警告,但是一定要對所有警告產生的原因有所瞭解,要知道在特定專案中那些警告式可以忽略的,那些警告的出現對結果會有影響,應當避免。

5、沒有使用(很少使用)列表推導式

列表推導式是 python 的一個非常強大的特性。許多 for 迴圈可以用更易讀、更 Python 且速度更快的列表推導來代替。

可以在下面看到一個示例程式碼,該程式碼旨在讀取目錄中的 CSV 檔案。可以看到,在使用列表推導時添很容易維護。

 import pandas as pd
 import os
 
 DATA_PATH = "data"
 filename_list = os.listdir(DATA_PATH)
 
 #### 不好的方法 #####
 csv_list = []
 for fileaname in filename_list:
  csv_list.append(pd.read_csv(os.path.join(DATA_PATH, filename)))
   
 #### 建議 ####
 csv_list = [pd.read_csv(os.path.join(DATA_PATH, filename)) for filename in filename_list]
 list comprehensions
 csv_list = [pd.read_csv(os.path.join(DATA_PATH,
        filename)) for filename in filename_list if    
        filename.endswith(".csv")]

6、不使用型別註釋

型別註釋(或型別提示)是為變數分配型別的方法。在IDE進行智慧感知的提示時可以為我們提供指示變數/引數的型別。這不僅可以提高我們開發的速度,也可以對我們閱讀程式碼有很大的幫助

 def mystery_combine(a, b, times):
    return (a + b) * times

如果這麼寫,我們根本不知道a,b和times的型別

 def mystery_combine(a: str, b: str, times: int) -> str:
    return (a + b) * times

但是加上了型別註釋,我們就知道a和b是字串times是整數

需要說明的是:python在3.5版本的時候引入了型別註釋,python並不會在執行時檢查型別註釋,他只是為IDE提供了一個方便靜態型別檢查工具,對動態語言做靜態型別檢查,來避免一些潛在的錯誤。

7、pandas程式碼不規範

方法鏈是 pandas 的一個很棒的特性,但是如果在一行中包含了很多的操作,程式碼可能會變得不可讀。

有一個技巧可以讓這種方式邊的簡單,將表示式放入括號中,則可以對錶達式的每個元件使用一行。

 var_list = ["clicks", "time_spent"]
 var_list_Q = [varname + "_Q" for varname in var_list]
 
 #不可讀的方法
 df_Q = df.groupby("id").rolling(window=3, min_periods=1, on="yearmonth[var_list].mean().reset_index().rename(columns=dict(zip(var_list, var_list_Q)))
 
 #可讀性強的方法
 df_Q = (
    df
    .groupby("id")
    .rolling(window=3, min_periods=1, on="yearmonth")[var_list]
    .mean()
    .reset_index()
    .rename(columns=dict(zip(var_list, var_list_Q))))
    

8、不遵守 PEP 約定

剛開始使用 Python 進行程式設計時,程式碼可能是簡陋並且不可讀的,這是因為我們並沒有自己的設計規則來讓我的程式碼看起來更好。如果我們自己來設計這種規則是費事費力的並且這種規則需要很多的實踐,好在Python官方有已經指定好的規則:PEP,它是 Python 的官方樣式指南。

雖然PEP的規則很多並且很繁瑣,我們可以忽略了一些 PEP 規則,但可以在 90% 的程式碼中使用了它們。

9、你不使用編碼輔助工具

您想在編碼方面大幅提高生產力嗎?請開始使用編碼輔助工具,它透過巧妙的自動完成、開啟文件和提供改進程式碼的建議來提供幫助。

pylance, Kite ,tabnine,copilot都是非常好的選擇。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70023145/viewspace-2920524/,如需轉載,請註明出處,否則將追究法律責任。

相關文章