讀取、創(chuàng)建和運(yùn)行多個(gè)文件的3個(gè)Python技巧
動(dòng)機(jī)
將代碼投入生產(chǎn)時(shí),你很可能需要處理代碼文件的組織。讀取、創(chuàng)建和運(yùn)行許多數(shù)據(jù)文件非常耗時(shí)。本文將向你展示如何自動(dòng)
- 循環(huán)訪問目錄中的文件
- 如果不存在嵌套文件,創(chuàng)建它們
- 使用bash for loop運(yùn)行一個(gè)具有不同輸入的文件
這些技巧為我在數(shù)據(jù)科學(xué)項(xiàng)目中節(jié)省了很多時(shí)間。我希望你也會(huì)發(fā)現(xiàn)它們有用!
循環(huán)訪問目錄中的文件
如果我們要像這樣讀取和處理多個(gè)數(shù)據(jù):
- ├── data
- │ ├── data1.csv
- │ ├── data2.csv
- │ └── data3.csv
- └── main.py
我們可以嘗試一次手動(dòng)讀取一個(gè)文件
- import pandas as pd
- def process_data(df):
- pass
- df = pd.read_csv(data1.csv)
- process_data(df)
- df2 = pd.read_csv(data2.csv)
- process_data(df2)
- df3 = pd.read_csv(data3.csv)
- process_data(df3)
當(dāng)我們有3個(gè)以上的數(shù)據(jù)時(shí),這是可以的,但不是有效的。如果我們?cè)谏厦娴哪_本中只更改了數(shù)據(jù),為什么不使用for循環(huán)來訪問每個(gè)數(shù)據(jù)呢?
下面的腳本允許我們遍歷指定目錄中的文件
- import os
- import pandas as pd
- def loop_directory(directory: str):
- '''循環(huán)目錄中的文件'''
- for filename in os.listdir(directory):
- if filename.endswith(".csv"):
- file_directory = os.path.join(directory, filename)
- print(file_directory)
- pd.read_csv(file_directory)
- else:
- continue
- if __name__=='__main__':
- loop_directory('data/')
- data/data3.csv
- data/data2.csv
- data/data1.csv
以下是對(duì)上述腳本的解釋
- for filename in os.listdir(directory):循環(huán)訪問特定目錄中的文件
- if filename.endswith(".csv"):訪問以“.csv”結(jié)尾的文件
- file_directory = os.path.join(directory, filename):連接父目錄('data')和目錄中的文件。
現(xiàn)在我們可以訪問“data”目錄中的所有文件!
如果不存在嵌套文件,創(chuàng)建它們
有時(shí),我們可能希望創(chuàng)建嵌套文件來組織代碼或模型,這使得將來更容易找到它們。例如,我們可以使用“model 1”來指定特定的特征工程。
在使用模型1時(shí),我們可能需要使用不同類型的機(jī)器學(xué)習(xí)模型來訓(xùn)練我們的數(shù)據(jù)(“model1/XGBoost”)。
在使用每個(gè)機(jī)器學(xué)習(xí)模型時(shí),我們甚至可能希望保存模型的不同版本,因?yàn)槟P褪褂玫某瑓?shù)不同。
因此,我們的模型目錄看起來像下面這樣復(fù)雜
- model
- ├── model1
- │ ├── NaiveBayes
- │ └── XGBoost
- │ ├── version_1
- │ └── version_2
- └── model2
- ├── NaiveBayes
- └── XGBoost
- ├── version_1
- └── version_2
對(duì)于我們創(chuàng)建的每個(gè)模型,手動(dòng)創(chuàng)建一個(gè)嵌套文件可能需要很多時(shí)間。有沒有辦法讓這個(gè)過程自動(dòng)化?是的,os.makedirs(datapath)。
- def create_path_if_not_exists(datapath):
- '''如果不存在,則創(chuàng)建新文件并保存數(shù)據(jù)'''
- if not os.path.exists(datapath):
- os.makedirs(datapath)
- if __name__=='__main__':
- create_path_if_not_exists('model/model1/XGBoost/version_1')
運(yùn)行上面的文件,你應(yīng)該會(huì)看到嵌套文件'model/model2/XGBoost/version_2'自動(dòng)創(chuàng)建!
現(xiàn)在你可以將模型或數(shù)據(jù)保存到新目錄中!
- import joblib
- import os
- def create_path_if_not_exists(datapath):
- '''如果不存在就創(chuàng)建'''
- if not os.path.exists(datapath):
- os.makedirs(datapath)
- if __name__=='__main__':
- # 創(chuàng)建目錄
- model_path = 'model/model2/XGBoost/version_2'
- create_path_if_not_exists(model_path)
- # 保存
- joblib.dump(model, model_path)
Bash for Loop:使用不同的參數(shù)運(yùn)行一個(gè)文件
如果我們想用不同的參數(shù)運(yùn)行一個(gè)文件呢?例如,我們可能希望使用相同的腳本來使用不同的模型來預(yù)測(cè)數(shù)據(jù)。
- import joblib
- # df = ...
- model_path = 'model/model1/XGBoost/version_1'
- model = joblib.load(model_path)
- model.predict(df)
如果一個(gè)腳本需要很長(zhǎng)時(shí)間才能運(yùn)行,而我們有多個(gè)模型要運(yùn)行,那么等待腳本運(yùn)行完畢然后運(yùn)行下一個(gè)腳本將非常耗時(shí)。有沒有一種方法可以告訴計(jì)算機(jī)用一個(gè)命令行運(yùn)行1,2,3,10,然后去做其他的事情。
是的,我們可以用for bash for loop。首先,我們使用系統(tǒng)argv使我們能夠解析命令行參數(shù)。如果要覆蓋命令行上的配置文件,也可以使用hydra等工具。
- import sys
- import joblib
- # df = ...
- model_type = sys.argv[1]
- model_version = sys.argv[2]
- model_path = f'''model/model1/{model_type}/version_{model_version}'''
- print('Loading model from', model_path, 'for training')
- model = joblib.load(model_path)
- mode.predict(df)
- >>> python train.py XGBoost 1
- Loading model from model/model1/XGBoost/version_1 for training
太好了!我們剛剛告訴我們的腳本使用模型XGBoost,version 1來預(yù)測(cè)命令行上的數(shù)據(jù)?,F(xiàn)在我們可以使用bash循環(huán)遍歷模型的不同版本。
如果你可以使用Python執(zhí)行for循環(huán),那么也可以在下面這樣的終端上執(zhí)行
- $ for version in 2 3 4
- > do
- > python train.py XGBoost $version
- > done
鍵入Enter分隔行
輸出:
- Loading model from model/model1/XGBoost/version_1 for training
- Loading model from model/model1/XGBoost/version_2 for training
- Loading model from model/model1/XGBoost/version_3 for training
- Loading model from model/model1/XGBoost/version_4 for training
現(xiàn)在,你可以在使用不同模型運(yùn)行腳本的同時(shí)執(zhí)行其他操作!多方便啊!
結(jié)論
祝賀你!你剛剛學(xué)習(xí)了如何同時(shí)自動(dòng)讀取和創(chuàng)建多個(gè)文件。你還學(xué)習(xí)了如何使用不同的參數(shù)運(yùn)行一個(gè)文件。手動(dòng)讀、寫和運(yùn)行文件的時(shí)間現(xiàn)在可以節(jié)省下來,用于更重要的任務(wù)。