博主之前特意說過,excel就是csv的一種,那麼在很多的商用數據中,不僅還用到csv還會用到excel,一旦數據量過大,綜合處理就會成爲一個問題,那麼這就是python高超的地方了,今天博主用一段較長的代碼來展示綜合的操作
那麼我們爲了能夠實現這段代碼的學習,我們需要幾個不同的文件。
下載地址
特意註明:博主所用的所有文件及代碼都是引用《python數據分析基礎》這本書的,其中的代碼或經過博主改動,所有的文件都可以在這個網址裏面下載到
我們打開這三個文件中任意一個會發現
開頭的Number都是這幾個數字,所以我們需要另外創建一個文件。使表格的開頭是這幾個數字,以便於後來的匹配。如圖:
這是博主的匹配文件及輸出文件。
我們不需要刻意去手動新建一個輸出的csv文件,因爲我們的python會幫我們創建
我們的目的是搜索出匹配開頭那幾個數字的所有數據,並找到其出處,成立出來
重點:我們需要進行搜索的三個文件一定要放在一個路徑下,這個路徑下不要帶有其他的excel或者csv文件,後面大家就會知道爲什麼。
準備工作完成,代碼
代碼:
import csv
import glob
import os
from datetime import date
from xlrd import open_workbook,xldate_as_tuple
items_find="E:\\桌面\\items_to_find.csv"
output_file="E:\\桌面\\output.csv"
items_to_find=[]
with open(items_find,"r",newline='') as item_number_csv_file:
filereader=csv.reader(item_number_csv_file)
for row in filereader:
items_to_find.append(row[0])
filewriter=csv.writer(open(output_file,"a",newline=""))#創建寫入對象
file_count=0
line_count=0
count_for_item_number=0
for input_file in glob.glob(os.path.join("E:\\桌面\\file_archive",'*.*')):#第一個問題,路徑需要用雙斜槓來寫
file_count+=1#文件讀取沒問題了
if input_file.split(".")[1]=="csv":
with open(input_file,"r",newline="") as fileread:
filereader=csv.reader(fileread)
header=next(filereader)
for row in filereader:
row_of_out=[]
for column in range(len(header)):
if column==3 :
cell_value=str(row[column]).strip("$").replace(",","").strip()
row_of_out.append(cell_value)
else:
cell_value=str(row[column]).strip()
row_of_out.append(cell_value)
row_of_out.append(os.path.basename(input_file))
if row[0] in items_to_find:#列表有問題。
filewriter.writerow(row_of_out)#肯定是寫入進去的,而寫入的唯一方法是這一條代碼
print(row_of_out)
count_for_item_number+=1
line_count+=1
#csv文件的問題解決之後,看xlsx文件的問題
elif input_file.split(".")[1]=="xls" or input_file.split(".")[1]=="xlsx":
workbook=open_workbook(input_file)
for worksheet in workbook.sheets():
try:
header=worksheet.row_values(0)
except IndexError:
pass
for row in range(1,worksheet.nrows):
row_of_out=[]
for column in range(len(header)):
if worksheet.cell_type==3:
cell_value=xldate_as_tuple(worksheet.cell_value(row,column),workbook.datemode())
cell_value=str(date(*cell_value[0:3])).strip()
row_of_out.append(cell_value)
else:
cell_value=str(worksheet.cell_value(row,column)).strip()
row_of_out.append(cell_value)
row_of_out.append(os.path.basename(input_file))
row_of_out.append(worksheet.name)
if str(worksheet.cell_value(row,0)).split(".")[0].strip() in items_to_find:
filewriter.writerow(row_of_out)
count_for_item_number+=1
line_count+=1
- 頭文件:處理多個多個文件自然而然要使用到glob,與os模塊,所以開頭引用。既然還要處理excel文件,那麼我們又得注意引用datetime模塊來格式時間,已經excel的讀取模塊xlrd
- 前面幾行我們把需要匹配的數字都寫入這個列表中,相信小夥伴們也能意識到,這個所謂的
完全是多餘,哈哈沒想到吧,其實我們只需要把所有需要匹配的數字填入一個列表中即可,這樣做其實是爲了以後處理特別大的csv或者excel時,我們這樣會稍微方便一點。整個10到13行博主覺得完全是作者的惡趣味…。 - **filewriter=csv.writer(open(output_file,“a”,newline=""))**創建寫入對象,這裏小夥伴已經非常熟悉了。但是這個寫法博主以前應該一直是使用以下寫法寫的。
其實兩者是完全等價的,但是下面會對比較白的小夥伴比較友好,稍微熟悉的小夥伴就可以按博主上面的“新寫法寫”,簡單,大氣,上檔次。 - 我們創建三個變量來計數。
- **for input_file in glob.glob(os.path.join(“E:\桌面\file_archive”,’.’))**這裏我們使用for循環,glob以及os來讀取這個路徑下所有的文件,這個 前後的星號代表的是文件的名字和後綴,這樣寫代表所有文件,當然你可以後面的星號改爲xlsx這樣就只會讀取所有的xlsx文件。
- 接下來我們來判斷需要處理的是csv還是excel,我們只需要使用split函數將文件名以 . 隔開成爲一個列表,利用他的後綴判斷即可。
- if 後面的模塊不需要講解,相信小夥伴已經非常熟悉了,就是之前處理兩種文件的不同寫法。值得一提的是,這裏我們用到了tyr expect語句,這個屬於python中的異常處理,非常有用,大家可以去這裏瞭解一下。
- 前面博主特意提醒不要將那個沒用的items_to_find.csv與需要搜索的三個文件放在一個路徑就是因爲他也是一個csv文件,那麼我們讀取整個路徑自然會讀取到它,而它又只有幾行沒用的數字,那樣我們的輸出文件裏面就會多出來幾行完全沒用的數據,雖然無傷大雅,但是對強迫症患者很不友好。