エラー時の切り分けとバックアップ|PC・ブラウザ・ファイルの基本
このページはプロモーション(広告)を含みます。
PC・ブラウザ・ファイルの基本(初級・読む25分+演習35分)
この授業のゴール
- エラーメッセージを読み、層(ファイル名・文字コード・列名・値)ごとに原因を切り分けられる
- 原因を1つずつ変えて確かめる手順(再現→仮説→1か所変更→記録)を実行できる
- 日付付きの名前でバックアップを作り、ハッシュ値で原本と同じ内容か確かめられる
- CSVを読み込み、行数と列を確認し、ノートと結果を出力して再読込で一致を確かめられる
仕事でどう使うか
エラーに出会わない人はいません。仕事で差がつくのは、エラーが出たときに、闇雲に操作せず、原因を絞り込めるかです。そしてもう1つが、失敗しても元に戻せる状態を、あらかじめ作っておくことです。
| 路線 | この授業の使いどころ |
|---|---|
| DS(データサイエンティスト) | 「ファイルが読めない」「列がない」に出会ったとき、エラー文から原因を特定する。分析の途中結果を日付付きで残し、やり直しの時間を減らす |
| ML(機械学習エンジニア) | 学習が途中で止まったとき、データ・コード・環境のどこの問題かを切り分ける。モデルと設定のファイルをバックアップして実験を再現する |
| DX(DX推進・AI企画) | 現場から来た「動かない」という報告から、再現手順と環境情報を聞き出す。バックアップの頻度と保管場所を運用ルールに書く |
| RS(研究者) | 実験データの紛失は研究の失敗になる。原本のコピーを別の場所に持ち、同一性を確認できる状態にする |
この授業で、ON01の統合演習(CSVを読み込み、行を確認し、ノートと結果を出力して再読込する)を行います。
前提
前提は、画面とブラウザの役割(層の区別)、ファイル・フォルダ・拡張子(原本を残す)、保存・ダウンロード・アップロード(保存先と上書き)、文字コードと安全なファイル確認(文字コードの確認)です。診断を省略して始めた場合は、各授業の「失敗」の節だけ読み返してから進めても構いません。
- 例外(exception):Pythonの実行中に起きたエラー。名前(
FileNotFoundErrorなど)とメッセージが付く - ハッシュ値:ファイルの内容から計算する短い固定長の文字列。内容が1バイトでも違うと別の値になる
- pandas:表データを扱うPythonの道具。
pd.read_csv(パス)はCSVを読み、表(DataFrame)を返す
復元(バックアップから元に戻す手順)の詳しい説明は、この授業の最後の任意の節にまとめました。
身近な状況:「動きません」と言われたとき
Gさんは、同僚から「CSVが読めません」と連絡を受けました。Gさんは、最初の対応を3つ思いつきました。
- パソコンを再起動してもらう
- ファイルをもう一度ダウンロードしてもらう
- エラーの文を読んでもらう
3つ目が最も早い方法です。エラーの文には、何が・どこで・どう悪かったかの手がかりが入っています。ところが、慌てると読まずに操作を繰り返し、元のファイルを上書きして状況を悪化させがちです。
エラーの切り分けとは、原因の候補を、層ごとに1つずつ消していく作業です。画面とブラウザの役割 で学んだ層(PC・OS・ブラウザ・アプリ・データ)に、ファイルの層(名前・場所・形式・文字コード・中身)を足して考えます。
| 症状(エラー名) | まず疑う原因 | 確認すること |
|---|---|---|
FileNotFoundError |
名前・場所・作業フォルダ | スペル、拡張子、フォルダ、相対か絶対か |
UnicodeDecodeError |
文字コード | UTF-8かCP932か、BOM |
KeyError |
列名 | 大文字小文字、空白、全角半角、BOM |
ValueError |
値の形 | カンマ、空白、全角数字、欠損 |
PermissionError |
権限・使用中 | 他のアプリで開いていないか、保存先 |
直感的な説明:問診と、1か所だけ変える原則
切り分けは、医者の問診に似ています。
- いつから・何をしたとき起きるか(再現手順)
- どこで起きるか(自分のPCだけか、他の人もか)
- 前は動いていたか、何が変わったか
- 検査は1つずつ行う(複数の薬を同時に変えると、どれが効いたか分からない)
特に大事なのは、1度に変えるのは1か所という原則です。ファイル名とフォルダと文字コードを同時に変えて動いたとしても、何が原因だったのか分かりません。次に同じことが起きたとき、また同じ苦労をします。
バックアップは、問診の前に取る保険です。切り分けの途中でファイルを壊しても、元に戻せるなら、思い切って試せます。
たとえの限界:人体と違い、データは完全に複製できます。複製が元と同じかどうかも、ハッシュ値で確かめられる点が、データならではの強みです。
正確な定義:切り分けの手順、ハッシュ、3-2-1の考え方
切り分けの5手順
- エラー文を全部読む:例外の名前、メッセージ、最後に出た行を書き写す。
- 再現手順を書く:同じエラーを、もう一度起こせる最短の手順にする。
- 層を決める:名前・場所・形式・文字コード・列名・値の、どれかに当てはめる。
- 1か所だけ変えて再実行:結果をメモする。
- 記録する:原因と直し方を1行残す。
エラー文は、例外の名前とメッセージでできています。実際に確かめましょう。
import pandas as pd
def attempt(label, fn):
try:
fn()
except Exception as e:
print(label, "->", type(e).__name__, ":", str(e)[:70])
attempt("1", lambda: open("/data/ab_tset.csv"))
attempt("2", lambda: open("/data/churn.csv", encoding="cp932").read())
attempt("3", lambda: pd.read_csv("/data/ab_test.csv")["convert"])
attempt("4", lambda: int("1,200"))
出力は、1 -> FileNotFoundError : [Errno 44] No such file or directory: '/data/ab_tset.csv'、2 -> UnicodeDecodeError : 'cp932' codec can't decode byte 0x8d in position 145: illegal multibyt、3 -> KeyError : 'convert'、4 -> ValueError : invalid literal for int() with base 10: '1,200' です。1は ab_test のスペルミス(名前の層)、2は文字コード、3は列名 converted の打ち間違い、4はカンマ入りの文字列(クリック・入力・選択・コピー)です。メッセージの中に、ファイル名、バイト位置、列名、値そのものが書かれています。
ハッシュ値:ファイルの全バイトから計算する固定長の文字列で、内容が同じなら必ず同じ値、1バイトでも違えば(ほぼ確実に)別の値になります。hashlib.sha256(バイト列).hexdigest() は、バイト列(bytes)を受け取り、64文字の16進数の文字列を返します。
バックアップの3-2-1の考え方(一般的な目安):コピーを3つ持ち、2種類の保管先に分け、1つは離れた場所に置く。同じフォルダの中にコピーを置いても、フォルダごと消えたら両方失われます。
段階付き例題:統合演習 ― CSVを読み、確認し、出力し、再読込する
問題:教材の ab_test.csv(架空のA/Bテスト。1行=1ユーザー)を読み込み、行を確認し、結果とノートを出力し、再読込して一致を確かめる。
ステップ1:読み込んで形を確認する(入力→処理)。df.shape(行数・列数のタプル)、df.dtypes(列ごとの型)、欠損の合計を見る。
ステップ2:集計する(処理)。group(A/B)ごとの購入率 converted.mean()。converted は購入したら1、しなければ0の列なので、平均は購入者÷ユーザー数です。分母はユーザー数(各群の行数)で、購入した人だけではありません。
ステップ3:出力して再読込する(出力→検証)。結果をCSV、ノートをテキストに書き、読み直す。
import pandas as pd, tempfile, pathlib
df = pd.read_csv("/data/ab_test.csv")
print(df.shape)
print(df.dtypes.astype(str).to_dict())
print(int(df.isna().sum().sum()))
print(df["group"].value_counts().sort_index().to_dict())
rate = df.groupby("group")["converted"].mean()
print(rate.round(4).to_dict())
out = pathlib.Path(tempfile.mkdtemp())
rate.round(4).to_csv(out / "result.csv", header=["conversion_rate"])
(out / "note.txt").write_text("ab_test.csv: %d rows\n" % len(df), encoding="utf-8")
back = pd.read_csv(out / "result.csv")
print(back)
print(back.shape, (out / "note.txt").read_text(encoding="utf-8").splitlines()[0])
print(round((rate["B"] - rate["A"]) * 100, 2))
出力は次のとおりです。
(4000, 6):4000行・6列- 列の型:
user_id・visits・converted・revenueはint64、group・deviceはobject(文字列) 0:欠損なし{'A': 2021, 'B': 1979}:群ごとのユーザー数(これが分母){'A': 0.0955, 'B': 0.1081}:購入率(約9.55%と約10.81%)- 再読込した表は2行2列(
group、conversion_rate)で、ノートの1行目はab_test.csv: 4000 rows 1.26:群Bと群Aの差は1.26パーセントポイント
ステップ4:意味を言葉にする。9.55%と10.81%の差は「1.26ポイント」で、「1.26%の上昇」ではありません(割合の差と、割合そのものの変化率は別の量)。この差が偶然か意味のある違いかは、この授業では判断しません。ここでは、読み込み・確認・出力・再読込の手順が正しく回ることを確認しました。
操作して理解する:バックアップを取り、同じか確かめ、壊れた例を見る
次のコードで、(1) 日付付きの名前でコピー、(2) ハッシュ値の比較、(3) 途中で切れたコピーの検出、(4) フォルダごと消えたときの被害、を順に確認します。
import hashlib, shutil, tempfile, pathlib
root = pathlib.Path(tempfile.mkdtemp())
src = root / "a.csv"
src.write_text("id\n1\n2\n", encoding="utf-8")
def sha(p):
return hashlib.sha256(pathlib.Path(p).read_bytes()).hexdigest()
print(sha(src)[:16])
(root / "bk").mkdir()
dst = shutil.copy(src, root / "bk" / "a_2026-10-10.csv")
print(sha(src) == sha(dst))
dst2 = root / "bk" / "a_trunc.csv"
dst2.write_text("id\n1\n")
print(sha(src) == sha(dst2), len(src.read_bytes()), len(dst2.read_bytes()))
shutil.rmtree(root)
print(src.exists(), pathlib.Path(dst).exists())
出力は、1d1c91d15ace6e21(ハッシュの先頭16文字)、True(正しいコピーは一致)、False 7 5(途中で切れたコピーは不一致、7バイトと5バイト)、False False(フォルダごと消すと、元もコピーも両方なくなる)です。
考えてみる:
- 最後の
rmtreeをshutil.rmtree(root / "bk")に変えると、src.exists()はどうなるか。(答え:True。バックアップだけが消えます。) - バックアップを別の保管先に置くとは、実際の画面では、どこに置くことか。(例:別のドライブ、別のサービス、別の端末。)
実際の画面では、ファイルのプロパティで「サイズ」を比べるだけでも、途中で切れたコピーを見つけられます。バックアップは取ったら、同じかどうかを確かめて初めて、取れたことになります。
発展(任意):復元の手順と、質問の書き方
この節は任意です。ON01の目標(ここまでの手順を使って、CSVを読み、結果を保存し、再読込で確かめる)は、前の節までで達成できます。
復元の手順(バックアップから元に戻す):
- 現状を残す:壊れたファイルを上書きせず、別の名前(例:
broken_を付ける)で退避する。 - 復元元を選ぶ:日付とハッシュ値で、どのバックアップが正しいか確認する。
- 別の場所に復元する:いきなり元の場所に戻さず、作業用フォルダで中身を確認する。
- 確認してから置き換える:行数や代表値が、記録と合うことを確かめる。
- 記録する:いつ、どの版から戻したか。
復元の練習をしていないバックアップは、取れたかどうかが分かりません。定期的に、小さなファイルで復元の練習をします。
質問の書き方:他の人に助けを求めるときは、次の5点を書くと解決が早くなります。(1) したかったこと、(2) 実際に起きたこと(エラー文の全文)、(3) 再現手順、(4) 環境(OS、ブラウザ、版)、(5) すでに試したこと。個人情報や機密を含む部分は、伏せてから共有します。
よくある失敗
失敗1:エラー文を読まずに、同じ操作を繰り返す
誤った対応:KeyError が出たので、ファイルを開き直す、再実行する、を繰り返した。
import pandas as pd
df = pd.read_csv("/data/ab_test.csv")
print(list(df.columns))
try:
df["convert"]
except KeyError as e:
print("KeyError:", e)
print("converted" in df.columns)
出力は ['user_id', 'group', 'device', 'visits', 'converted', 'revenue']、KeyError: 'convert'、True です。エラー文に、探した名前('convert')が書かれており、実際の列名(converted)は列の一覧で確認できます。
直し方:エラー名とメッセージを書き写し、df.columns などで実際にある名前を確かめる。再実行を繰り返す前に、読む。
失敗2:バックアップを元のファイルと同じフォルダに置く
誤った運用:data フォルダの中に data_backup.csv を作り、バックアップのつもりになった。
import tempfile, shutil, pathlib
root = pathlib.Path(tempfile.mkdtemp())
data = root / "data"
data.mkdir()
(data / "data.csv").write_text("id\n1\n", encoding="utf-8")
shutil.copy(data / "data.csv", data / "data_backup.csv")
shutil.rmtree(data) # フォルダごと削除(誤操作)
print((data / "data.csv").exists(), (data / "data_backup.csv").exists())
出力は False False です。コピーが同じ場所にあると、同じ原因(フォルダの削除、ディスクの故障)で同時に失われます。
直し方:別のフォルダ、できれば別のドライブや別のサービスに置く(3つのコピー、2種類の保管先、1つは離れた場所)。
失敗3:バックアップを取っただけで、同じか確かめない
誤った運用:コピー中に処理が止まり、途中までしかない report_backup.csv ができたが、気付かず安心した。
import hashlib
orig = ("id,amount\n" + "\n".join(f"{i},{i*100}" for i in range(1, 6)) + "\n").encode()
partial = orig[:25]
print(len(orig), len(partial))
print(hashlib.sha256(orig).hexdigest() == hashlib.sha256(partial).hexdigest())
出力は 40 25(バイト数)と False です。サイズも内容も違います。
直し方:バックアップのあとで、サイズとハッシュ値を比べる。行数や代表値(合計など)も、元と照合して記録する。
まとめ
- エラーは、名前とメッセージを最後まで読む。ファイル名・列名・値・バイト位置などの手がかりが書かれている。
- 切り分けは、再現手順→層の特定→1か所だけ変更→記録。1度に複数を変えない。
- バックアップは、日付付きの名前で、別の場所に置き、ハッシュ値で同じか確かめて初めて取れたと言える。
- 統合演習:CSVを読み、行数・列・型・欠損を確認し、結果とノートを出力して再読込して一致を確かめる。
用語
- 例外(exception)
Pythonの実行中に起きたエラー。名前(FileNotFoundError など)とメッセージで原因の手がかりを示す。
- 切り分け(troubleshooting / isolation)
原因の候補を層ごとに1つずつ確かめて絞り込む作業。
- ハッシュ値(hash value)
ファイルの全バイトから計算する固定長の文字列。内容が同じなら同じ値になる。
- バックアップ(backup)
元のデータが失われても戻せるように、別の場所に作っておくコピー。
- DataFrame(DataFrame)
pandasの表データ。行と列を持ち、列ごとに型がある。
よくある質問
エラーメッセージが英語で、読めません。どうすればよいですか?
全部を訳す必要はありません。例外の名前(FileNotFoundError など)と、メッセージの中の固有の語(ファイル名、列名、値)を拾います。名前だけで、前の表のどの層かが分かるようになります。翻訳ツールを使うときは、個人情報を含む部分を伏せてください。
バックアップはどのくらいの頻度で取るべきですか?
失ったときに、やり直せる量で決めます。1日分の作業を失っても許容できないなら、毎日です。節目(分析の前、大きな編集の前)に取る習慣が基本で、頻度は組織のルールに従います。
クラウドの同期サービスは、バックアップになりますか?
完全にはなりません。誤った編集や削除も同期されるからです。ただし、履歴機能やごみ箱で戻せる場合もあります。履歴の保存期間は変わり得るので、公式情報で確認し、重要なものは別の場所にもコピーを持ちます。
ハッシュ値とは、何を保証するのですか?
内容が同じなら同じ値、違えば(ほぼ確実に)違う値になることです。コピーが同一かの確認に使えます。ただし、「中身が正しいか」「安全か」までは保証しません。
エラーが再現しないときは、どうすればよいですか?
そのときの環境、手順、入力ファイルを記録します。再現しない場合も、日時、画面の状況、エラー文を残しておくと、次に出たときに比べられます。偶然に任せて放置せず、記録を残すことが大切です。
仕事で「動かない」と相談されたら、まず何を聞きますか?
(1) 何をしようとしたか、(2) エラー文の全文、(3) 前は動いていたか、(4) 何が変わったか、(5) 環境(OS、ブラウザ)を聞きます。そのうえで、層を一つずつ確認します。ここで質問を整理できる力が、DX推進の仕事で役に立ちます。
確認問題
問1 エラーが出たとき、最初にすべきことはどれか。
- ① PCを再起動する
- ② エラーの名前とメッセージを最後まで読み、書き写す
- ③ ファイルを削除して作り直す
- ④ 同じ操作を何度か繰り返す
解答と解説
正解:②
エラー文には、原因の手がかり(ファイル名、列名、値、位置)が書かれています。読まずに操作すると、状況を悪化させることがあります。
問2 KeyError: 'convert' が出た。最も可能性が高い原因はどれか。
- ① ファイルが見つからない
- ② 文字コードが違う
- ③ メモリが足りない
- ④ 探した列名
convertが存在せず、実際はconvertedなどのスペル違い
解答と解説
正解:④
KeyError は、辞書や表で、指定した名前が無いときに出ます。メッセージの中の名前と、実際の列名を比べます。
問3 切り分けで「1度に変えるのは1か所」とするのはなぜか。
- ① 複数を同時に変えると、どの変更が効いたのか分からなくなるから
- ② 操作の回数を増やすため
- ③ エラーを隠すため
- ④ ルールとして決まっているだけで、理由はない
解答と解説
正解:①
原因を特定し、次に同じ問題が出たときに再利用するためです。複数を同時に変えると、偶然直った場合も原因が分かりません。
問4 バックアップを、元のファイルと同じフォルダに data_backup.csv として置いた。この運用の最大の問題はどれか。
- ① ファイル名が長いこと
- ② 拡張子が同じこと
- ③ フォルダの削除やディスクの故障で、元とコピーが同時に失われること
- ④ ファイルサイズが倍になること
解答と解説
正解:③
同じ場所にあるコピーは、同じ原因でまとめて失われます。別の場所、できれば別種類の保管先に置きます。
問5 コピーが元と同じ内容か確かめる方法として、最も確実なものはどれか。
- ① ファイル名が同じことを確認する
- ② 更新日時を見る
- ③ ファイルを開いて、最初の1行だけ見る
- ④ ハッシュ値(sha256 など)を比べる
解答と解説
正解:④
ハッシュ値は全バイトから計算するので、1バイトの違いも検出できます。名前、日時、先頭行では、途中で切れたコピーを見逃すことがあります。
問6 except ValueError を except UnicodeDecodeError より先に書くと、何が起こるか。
- ① UnicodeDecodeError は発生しなくなる
- ② UnicodeDecodeError も ValueError の分岐に入ってしまう
- ③ プログラムが動かなくなる
- ④ 何も変わらない
解答と解説
正解:②
UnicodeDecodeError は ValueError のサブクラスなので、先に ValueError を書くとそこで捕まります。具体的な型を先に書きます。
次に学ぶこと
これでON01の6授業は終わりです。次は、総合テストと自力課題で到達度を確認します。その後は、データの1行が何を表すかを学ぶ 表・単位・割合・グラフ や、表計算の基本を扱う授業へ進めます。前の授業に戻るなら、保存先は 保存・ダウンロード・アップロード、文字コードは 文字コードと安全なファイル確認 です。
この授業の確認問題だけでモジュールの習得とはしません。ON01 の総合テストと、CSVを使った自力課題で判定します。
キャリア学習:データサイエンティスト・機械学習エンジニア・DX推進・研究者を目指す人の学習アプリ。164モジュール・984授業を、ブラウザで動くSQLとPythonの演習で。基礎と各分野の最初のモジュールは無料。全部は2,980円の買い切り。
アプリを無料で開く有料版と無料版の違い