在數據分析的日常工作中,我們可能會經常需要處理這樣的問題:將一個或多個文件夾下的文件中的數據進行分析、處理、整合。這些文件通常是相似的或是同類別的,比如我們有多個月份的銷售信息,每個月份的數據分別存在一個excel文檔中;多個類別的銷售信息,每個類的數據分別存在一個excel文檔中等等。像是如圖中所示:
在當前文件夾中存在「files」文件夾,裡面是我們將要分析的數據,在該文件夾目錄下又有如下四個文件夾,我們可以看作是四個大類的數據:
這四個文件夾當中就分別存放著所對應的數據,隨便打開其中一個文件夾,數據文件如圖所示:
其中每個文件的內容大致是相同:
所有文件共有128個,每個文件中條目數在幾百行,我們需要分別對這些文件中的數據進行分析,求出每個文件中所屬類目的起始日期、終止日期、平均轉化率、平均客單價,然後匯總到一起輸出一份數據分析報告。如果用excel來一個個處理的話需要處理128次,想想就覺得費力啊!那麼這個時候用上我們的pandas就再合適不過了。這個時候有些朋友會有些疑惑,我們該如何遍歷這些文件並讀取數據呢?本文就通過os庫以及pathlib庫為大家講解,並在最後重點介紹一下pathlib。
首先導入我們需要使用到的庫:
import pandas as pdimport numpy as npimport osfrom pathlib import Pathimport time設置自己存放文件的根目錄:
file_path = "/Users/***/jupyter_notebook/Python_file_processing/files"先用os的方法,這裡我們使用os.walk()來遍歷文件名:
可以看到每次遍歷都包含當前文件夾的根路徑、該文件夾下的文件夾、該文件夾下的所有文件列表。通過代碼我們可以輕鬆地將所有文件名整理到一個列表中:
# 存放所有文件名file_list = []# 存放每個子文件夾下所對應的文件名file_dict = {}for iroot, idirs, ifiles in os.walk(file_path): if not idirs: ifiles.remove('.DS_Store') file_list.extend(ifiles) file_dict[iroot] = ifiles因為pandas讀取文件需要絕對路徑,所以我們建立一個根路徑與文件名對應的字典,之後拼湊成絕對路徑。file_dict如下圖所示:
這樣我們就可以通過dict.items()來拼接文件的絕對路徑了,然後遍歷讀取文件,分析我們所需要的指標:
start_time = []end_time = []conversion_mean = []category = []unit_price_mean = []
start = time.time()# 遍歷所有文件,拼接路徑for k, v in file_dict.items(): for i in v: file_name = os.path.join(k, i) file = pd.read_excel(file_name) start_time.append(file['日期'].min()) end_time.append(file['日期'].max()) conversion_mean.append(file['轉化率'].mean()) category.append(file['三級類目'].unique()[0]) # 文件中有inf值 unit_price_mean.append(file['客單價'].replace(np.inf, np.nan).dropna().mean())
output_file = pd.DataFrame({'起始日期': start_time, '終止日期': end_time, '平均轉換率': conversion_mean, '所屬類目': category, '平均客單價': unit_price_mean})cost = round(time.time() - start, 2)print(f'處理數據共用時{cost}秒')最後輸出分析報告,共128個條目:
接下來我們用pathlib來遍歷文件,可能比os要方便一些。
首先設置文件目錄:
讓我們看一下通過pathlib的方法是如何遍歷的:
# 所有以xlsx結尾的文件for file in p.rglob('*.xlsx'): print(file)可以看到,通過pathlib.Path.rglob()方法可以直接遍歷匯總所有文件的絕對路徑,直接用pandas讀取即可:
start_time = []end_time = []conversion_mean = []category = []unit_price_mean = []
start = time.time()# 直接遍歷出文件絕對路徑for file_name in p.rglob('*.xlsx'): file = pd.read_excel(file_name) start_time.append(file['日期'].min()) end_time.append(file['日期'].max()) conversion_mean.append(file['轉化率'].mean()) category.append(file['三級類目'].unique()[0]) unit_price_mean.append(file['客單價'].replace(np.inf, np.nan).dropna().mean())
output_file1 = pd.DataFrame({'起始日期': start_time, '終止日期': end_time, '平均轉換率': conversion_mean, '所屬類目': category, '平均客單價': unit_price_mean})cost = round(time.time() - start, 2)print(f'處理數據共用時{cost}秒')這樣,通過pandas的方法我們一下子就處理完了所有數據,只用時2秒,和手動用excel一個個處理相比太方便了,而pathlib庫的使用更加方便了我們代碼的編寫。
Pathlib簡介:
得到當前目錄:
拼接路徑,得到想要的文件的絕對路徑:
p_new = p.joinpath('files', 'files32_1', '戶外服裝&潛水服.xlsx')得到路徑文件:
得到路徑文件的名稱:
得到路徑文件的後綴:
得到路徑文件的上一級目錄:
得到路徑的每一級:
判斷路徑文件是否存在:
判斷路徑文件是否為文件夾:
判斷路徑文件是否為文件:
創建新文件夾:
p_dir = Path(Path.cwd().joinpath('created_dir'))p_dir.mkdir(exist_ok=True, parents=True)創建文件夾之前:
創建文件夾之後:
修改路徑文件的文件後綴(with_shuffix修改後綴,with_name修改文件名):
p_new.replace(p_new.with_suffix('.txt'))刪除路徑文件:
完整代碼可關注公眾號「數據科學與人工智慧技術」並發送文字「pathlib」獲取
感謝觀看!