以下範例採用一個從臺灣證券交易所網站下載的實際csv資料檔,從中取得當日ETF交易資料,把需要的欄位資料另存到一個csv檔案。即簡單的csv讀取與寫入的作法。
範例說明
先自行從臺灣證券交易所網站下載csv檔,過程如下:- 交易資訊 > 盤後資訊 > 每日收盤行情
- 資料日期為上週五:106-9-22
- 類別:全部(不含權證、牛熊證、可展延牛熊證)
- 按查詢後,選擇:CSV 下載
- 下載存檔
本文主題在csv資料,為避免主題失焦,這裡不解釋金融術語,只交代資料中的有關項目。這csv檔中包含了臺灣上市公司所發行證券以及各種ETF的當日收盤資料,本文只要其中的ETF資料。以這原始資料檔案來看,其中有1172行,其中所要擷取的ETF資料有100筆。
原檔案中的資料欄位很多,這裡只需要以下欄位:
- 證券代號
- 證券名稱
- 開盤價
- 最高價
- 最低價
- 收盤價
- 成交金額
讀取
原始csv檔案中資料的構成方式有幾個重點,讀取時要了解:- 檔案裡有空行,做為資料區段的區隔
- 每列資料之間的欄位以半形逗點做分隔,並以 " 符號括住資料
- ETF資料列開頭是個=符號,並以 " 括住證券代號
- 成交金額中採用了半形逗點標示千位數
以下是讀取工作的代碼,與部分註釋文字,在代碼之後再補上必要的說明。
import csv
# 來源與輸出檔
source = 'MI_INDEX.csv'
output = 'output.csv'
# 用來存放ETF列表。先放入表頭。
etf_lst = [['證券代號', '證券名稱', '開盤價', '最高價', '最低價', '收盤價', '成交金額']]
# 讀取資料,把其中的ETF資料調整後存入etf_lst中
with open(source, encoding='cp950', newline='') as rf:
csv_reader = csv.reader(rf, delimiter=',', quotechar='"')
for row in csv_reader:
if row and row[0][0] == '=':
code = row[0].replace('=', '').replace('"', '')
etf_lst.append([code, row[1], row[5], row[6], row[7], row[8], row[4].replace(',', '')])
來源檔採cp950編碼,讀取時最好指定正確。newline=''若沒指定,資料欄括號裡的斷行無法正確解譯。本範例沒這類資料,所以可省略。
csv.reader會回傳一個reader object。兩個參數中delimiter指的是CSV中的分隔符號,quotechar則是做為括號的字元。這裡這兩個的設置都是預設值,所以可以省略不寫,這裡是為了展示才寫出來。
reader object會迭代(iterate)rf中的每一列,所以可以逐列處理其中的資料。
每列中所要的資料欄位,其位置若以0做第一欄,則分別在0, 1, 5, 6, 7, 8, 4欄。這點請對照前述所需欄位。
rf中的來源資料中有空行,且如前所述,ETF代號的第一字元是=,所以用
if row and row[0][0] == '=':
來篩選所要的ETF資料。取得所要的一列資料後:- ETF代號要去除=與"符號
- 成交金額要去除,符號
上述代碼主要純粹為展示而寫,並不是最佳的方式,像ETF代碼的處理那行可改成:
code = row[0][2:-1]
但這麼寫,表面上並不易看出“去除=與"符號”這動作,而且也不是本文主題的重點。寫入儲存
再來把etf_lst寫入output.csv檔中:
# etf_lst內容儲存到輸出檔
with open(output, 'w', encoding='cp950', newline='') as wf:
csv_writer = csv.writer(wf, delimiter=',', quoting=csv.QUOTE_NONE)
csv_writer.writerows(etf_lst)
這裡不需要存括號字元,所以設置quoting=csv.QUOTE_NONE,這個是csv模組所定義的常數。因為資料量不大,所以一次寫入,用writerows()把etf_lst串列寫入。
若資料較大,最好採逐行寫入的方式(writerow()),像:
for row in etf_lst:
csv_writer.writerow(row)
或者不透過etf_lst,而是採讀一行就寫一行的方式。以上是csv模組的簡單使用,完整說明請見Python文件csv模組說明。參數說明可見其中的Dialects and Formatting Parameters。
完整的範例代碼重新整理如下,全部範例代碼、資料與輸出的檔案打包在此。
import csv
# 來源與輸出檔
source = 'MI_INDEX.csv'
output = 'output.csv'
# 用來存放ETF列表。先放入表頭。
etf_lst = [['證券代號', '證券名稱', '開盤價', '最高價', '最低價', '收盤價', '成交金額']]
# 讀取資料,把其中的ETF資料調整後存入etf_lst中
with open(source, encoding='cp950', newline='') as rf:
csv_reader = csv.reader(rf, delimiter=',', quotechar='"')
for row in csv_reader:
if row and row[0][0] == '=':
code = row[0].replace('=', '').replace('"', '')
etf_lst.append([code, row[1], row[5], row[6], row[7], row[8], row[4].replace(',', '')])
# etf_lst內容儲存到輸出檔
with open(output, 'w', encoding='cp950', newline='') as wf:
csv_writer = csv.writer(wf, delimiter=',', quoting=csv.QUOTE_NONE)
csv_writer.writerows(etf_lst)
沒有留言:
張貼留言