Python テキストファイルやcsvファイル R/Wの覚え書き (pathlib, csvライブラリ)
テキストファイルの文字コード判定や、csvファイル R/Wの覚え書き (pathlib, csvライブラリ)
ファイルを開く pathlib利用
from pathlib import Path pth = Path('./SampleFiles/customers.csv') # エンコードを指定してファイルオープン with pth.open(encoding="utf-8") as f: contents = f.read() print(contents) """ 氏名,郵便番号,都道府県,,, 赤松雅康,737-0834,広島県,呉市,瀬戸見町,1-10 黒田徹子,697-0054,島根県,浜田市,高田町,1-5 鶴岡希実,103-0011,東京都,中央区,日本橋大伝馬町,3-6 比嘉沙良,939-1313,富山県,砺波市,柳瀬,4-13-1 河原希,294-0301,千葉県,館山市,香,8-13 秋本美希,629-1273,京都府,綾部市,下原町,4-15 森下誠一郎,289-1605,千葉県,山武郡芝山町,大台,3-14-5 丸山真奈美,399-0722,長野県,塩尻市,柿沢,7-16 ... """
ファイルの文字コードが不明の時 - 文字コードを調べて、ファイルを読む
chardet ライブラリを利用する。
インストール
pip install chardet
インストールすると、コマンドラインからも利用できるようになる
% chardetect ./SampleFiles/customers.csv ./SampleFiles/customers.csv: utf-8 with confidence 0.99
使い方
from pathlib import Path import chardet pth = Path('./SampleFiles/customers.csv') # バイナリで読み込み、detectメソッドで判定 with pth.open(mode='rb') as f: raw = f.read() encoding = chardet.detect(raw)['encoding'] # chardet.detect(raw) が返すのはこんな値 # { # 'encoding': 'utf-8', # 'confidence': 0.99, # 'language': '' # } # 文字コードがわかったので改めて読み込み with pth.open(encoding=encoding) as f: contents = f.read() # あるいは、さっきのバイナリデータを変換 print(raw.decode(encoding)) """ 氏名,郵便番号,都道府県,,, 赤松雅康,737-0834,広島県,呉市,瀬戸見町,1-10 黒田徹子,697-0054,島根県,浜田市,高田町,1-5 鶴岡希実,103-0011,東京都,中央区,日本橋大伝馬町,3-6 比嘉沙良,939-1313,富山県,砺波市,柳瀬,4-13-1 河原希,294-0301,千葉県,館山市,香,8-13 秋本美希,629-1273,京都府,綾部市,下原町,4-15 森下誠一郎,289-1605,千葉県,山武郡芝山町,大台,3-14-5 丸山真奈美,399-0722,長野県,塩尻市,柿沢,7-16 ... """
関数化しておく
ただし、いったん全部読みこむので、対象ファイルがデカいと効率悪いかも。
from pathlib import Path import chardet def det_encoding(path): # 文字コード判定 """ with pth.open(mode='rb') as f: raw = f.read() return chardet.detect(raw)['encoding'] # 使い方 pth = Path('./SampleFiles/customers.csv') encoding = det_encoding(pth)
csvファイルの読み書き
# ex2_customers_filter.py import csv from pathlib import Path import chardet # 文字コードを判定して返す def det_encoding(path): with pth.open(mode='rb') as f: raw = f.read() return chardet.detect(raw)['encoding'] # メイン処理ここから if __name__ == "__main__": pth = Path('./SampleFiles/customers.csv') encoding = det_encoding(pth) # csvファイル読み込み with pth.open(encoding=encoding) as f: reader = csv.reader(f) # csv用のリーダー # [['氏名', '郵便番号', '都道府県', '', '', '']] 関東在住メンバーだけ抽出 KANTO = ("東京都", "神奈川県", "埼玉県", "千葉県", "茨城県", "群馬県", "栃木県") data_kanto = [row for row in reader if reader.line_num >2 if row[2] in KANTO] # csvファイルに書き出す pth_dst = Path('./customers_kanto.csv') with pth_dst.open(mode="w", encoding="utf-8", newline="") as f_dst: writer = csv.writer(f_dst) # csv用のライター for data in data_kanto: writer.writerow(data) # 1行分書き込み(リストorタプル型で渡す)
補足: reader.line_num で行番号が取れる
with pth.open(encoding='utf-8') as f: reader = csv.reader(f) for row in reader: print(f'{reader.line_num}: {row}') """ 1: ['氏名', '郵便番号', '住所', '', '', ''] 2: ['赤松雅康', '737-0834', '広島県', '呉市', '瀬戸見町', '1-10'] 3: ['黒田徹子', '697-0054', '島根県', '浜田市', '高田町', '1-5'] 4: ['鶴岡希実', '103-0011', '東京都', '中央区', '日本橋大伝馬町', '3-6'] 5: ['比嘉沙良', '939-1313', '富山県', '砺波市', '柳瀬', '4-13-1'] 6: ['河原希', '294-0301', '千葉県', '館山市', '香', '8-13'] 7: ['秋本美希', '629-1273', '京都府', '綾部市', '下原町', '4-15'] ... """