パス操作したい(pathlib)
1from pathlib import Path
パス操作をするための標準モジュールです。
Python3で新しく追加されました(はず)。
pathlib.Pathオブジェクトを使うことで、
os.pathモジュールと同じことが、
よりオブジェクトっぽく操作できます。
ファイル名のリストを取得したい
1p = Path("ディレクトリ名")
2fnames = sorted(p.glob("*.csv"))
ディレクトリ内にあるファイルの拡張子などを指定して、ファイル名のリストを取得できます。
Path.glob(パターン)だとジェネレーターが返ってくるので、
sortedして、ファイル名の順番に並べたリスト型に変換しています。
ファイルを開きたい(open)
1# ファイルを開いて、データを読み込む
2p = Path("入力ファイル名")
3with p.open("r") as f:
4 lines = f.read()
5
6# ファイルを開いて、データを書き込む
7o = Path("出力ファイル名")
8with o.open("w") as f:
9 f.write(lines)
openメソッドでファイル(のポインター)を取得できます。
また、コンテキストマネージャー(with ... as構文)と組み合わせて、
ファイル操作ができます。
注釈
読み込む/書き込むデータがテキストデータとわかっている場合は、
より簡便なread_text、write_textメソッドがあります。
1# これまでの開き方
2p = Path("ファイル名")
3with open(p, "r") as f:
4 # ファイル操作
Pathオブジェクトは、従来のopen関数の引数に直接渡すことができます。
ファイルから読み込みたい(read_text / read_bytes)
1p = Path("ファイル名")
2p.read_text(encoding="utf-8") # mode="r"
3p.read_bytes() # mode="rb"
reat_textメソッドで、ファイルからテキストデータを読み込めます。
エンコーディングはデフォルトでUTF-8ですが、encodingオプションで変更できます。
バイナリーデータを読み込む場合はread_bytesを使います。
これらのメソッドの内部処理では
コンテキストマネージャーを使っています。
1with p.open(mode="r", encoding="utf-8") as f:
2 lines = f.read()
openメソッドを使って、コンテキストマネージャーを明示的に書いたサンプルです。
テキストデータの場合はmode="r"、
バイナリデータの場合はmode="rb"に設定します。
ファイルに書き込みたい(write_text / write_bytes)
1p = Path("ファイル名")
2p.write_text("テキストデータ", encoding="utf-8") # mode="w"
3p.write_bytes("バイナリーデータ") # mode="wb"
write_textメソッドで、ファイルにテキストデータを書き込めます。
encodingオプションでエンコーディングを変更できます。
デフォルトはシステムのエンコーディングです(Linux/macOSだとutf-8)。
errorsオプションでエンコーディングエラーが発生した場合の処理方法を設定できます。
デフォルトはstrictでUnicodeEncodeErrorの例外が発生します。
newlineオプションで改行コードを変更できます。
デフォルトはNoneでシステムの改行コードが指定されます。
バイナリーデータを書き込む場合はwrite_bytesを使います。
これらのメソッドの内部処理では
受け取ったデータの型チェックと、
コンテキストマネージャーを使っています。
1# with...as構文
2with p.open(mode="w", encoding="utf-8") as f:
3 f.write("テキストデータ")
openメソッドを使って、コンテキストマネージャーを明示的に書いたサンプルです。
テキストデータの場合はmode="w"、
バイナリデータの場合はmode="wb"に設定します。
ディレクトリを作成したい(mkdir)
1p = Path("ディレクトリ名")
2p.mkdir()
mkdir メソッドでディレクトリを作成できます。
すでにディレクトリが存在している場合はFileExistsErrorとなります。
1p = Path("ディレクトリ名")
2try:
3 p.mkdir()
4except FileExistsError as e:
5 print("ディレクトリはすでに存在します")
上書きを防止したい場合は、、try ... except:でこのエラーをキャッチすればOKです。
1p = Path("ディレクトリ名/サブディレクトリ名/ファイル名.csv")
2# 親ディレクトリのPathオブジェクトを取得
3# p.parent => Path("ディレクトリ名/サブディレクトリ名")
4p.parent.mkdir(parents=True, exist_ok=True)
5p.write_text("テキストデータ")
中間ディレクトリも含めて作成することもできます。
ディレクトリを必ず作成したい場合は、parents=Trueとexist_ok=Trueオプションを設定します。
パスを連結したい
1fname = Path("../data", "data.csv")
2
3dname = Path("../data/")
4fname = data_dir / "data.csv"
複数の引数を指定すると、それらを連結したPathオブジェクトが生成できます。
Pathオブジェクトは/を使って連結できます。
Pathオブジェクトはファイルが存在しなくても作成できます。
パスを取得したい
1# ホームディレクトリ
2Path.home()
3
4# カレントディレクトリ
5Path.cwd()
ホームディレクトリとカレントディレクトリを取得するPathのクラスメソッドがあります。
Path.home()とPath.cwd()でそれぞれのディレクトリ名をPathオブジェクトとして取得できます。
パスを整理したい
1from pathlib import Path
2import pandas as pd
3from typing import Literal
4
5def resolve_paths(
6 src: Path | Literal["random"],
7 pattern: str = "*.csv"
8) -> Path | Literal["random"] | list[Path]:
9
10 # 1. 特別な値を優先して処理
11 if src == "random":
12 return "random"
13
14 # 2. Pathオブジェクトに正規化
15 path = Path(src)
16
17 # 3. パスを確認
18 if not path.exists():
19 raise FileNotFoundError(path)
20
21 # 4. ファイルの場合
22 if path.is_file():
23 files: list[Path] = [path]
24 return files
25
26 # 5. ディレクトリの場合
27 if path.is_dir():
28 files: list[Path] = sorted(path.glob(pattern))
29 return files
30
31 # 6. 念のため
32 raise RuntimeError(f"Unsupported path type: {path}")
33
34
35resolved = resolve_paths(src)
36if resolved == "random":
37 # pd.DataFrameをランダムな値で生成(別の関数)
38 pass
39else:
40 # 読み込んだファイルをひとつのpd.DataFrameに変換
41 df = pd.concat(pd.read_csv(p) for p in resolved)
データ解析するときに、よく使うファイル読み込みの構成です。
ファイルまたはディレクトリのどちらを指定しても、ひとつのpd.DataFrameに変換できます。
また、"random"などの条件で専用の処理にも分岐できます。
汎用性が高いためresolve_pathsという名前のヘルパー関数として使っています。