公式ドキュメントをちゃんと読めばわかる話だったのだが,探し方が悪くなかなか見つからなかったので備忘録としてまとめる.
実験データを読み込む
Pythonでテーブルデータを扱うときはpandasのDataFrameとして読み込むことが多い.
測定機器が吐き出した実験データはちゃんとしたCSVにはなっているとは限らず,機器ごとに様々な形式を取っている.
「最初の5行にだけ余分なことが書いてあって6行目からテーブルデータになっている」のように要らない箇所が予めわかっていればheader=6
のようにすれば良いが,状況によって行数が変わる場合はいちいち行数を確認するのは面倒である.
以下のように実験データの前後に一定の行頭符号が付いた付加情報が加わったファイルを読み込むときは,comment
に行頭文字を指定すればその行は飛ばして読み込まれる.
*RAS_DATA_START
*RAS_HEADER_START
*DISP_FMT_X "%.4f"
......
*MEAS_SCAN_UNIT_Y "counts"
*RAS_HEADER_END
*RAS_INT_START
10.0000 7.3333 1.0000
10.0100 6.3333 1.0000
......
79.9900 3.5834 1.0000
80.0000 4.7499 1.0000
*RAS_INT_END
*RAS_DATA_END
# import pandas as pd
df = pd.read_table(
file_name,
comment="*", # コメント開始の文字を1文字で指定
encoding="shift-jis", # encoding は毎度明示的に指定したほうが良い
sep="\s+", # 空白区切りならこのように指定する
header=None
)
※1 read_table
とread_csv
はデフォルト引数が違う以外は同じ動作をする(はず)のでどちらでも良い.テーブルデータなのでread_table
の方がわかりやすい気もする.
※2 このデータはXRDの測定データ.
文字列オブジェクトを直接読み込む
Python上のstringオブジェクトを直接pandasに読み込ませたい場合はio.StringIO
でラップするとできる.
例えばREPL環境で直接データをコピペしたとか(※3),テーブルデータが"[Start Data]"
と"[End Data]"
の間に記述されているのでこの間を取ってきたという(※4)文字列がある場合は
# import io
# import pandas as pd
# ファイルから読み込んで文字列として保持
with open(file_name, mode="r", encoding="shift-jis") as file:
s = file.read()
# START_STR から END_STR までを clip する
START_STR = "[Start Data]"
END_STR = "[End Data]"
t = s[s.find(START_STR)+len(START_STR)+1: s.find(END_STR)]
# 文字列を DataFrame に変換
df = pd.read_table(
io.StringIO(t),
sep="\s+",
header=None
)
のようにすれば良い.
※3 クリップボードから直接読み込む pandas.read_clipboard
が存在するのでそれだけならこれを使ったほうが良い.
※4 単純にclipしたいだけなら無視する行番号をskiprows
で指定できるが,skipする行を全部渡す必要があるしファイルに2度アクセスすることになるのでどちらが早いかは微妙.
※5 CSVは意外とコーナーケースがある(クォーテーションや区切り文字を含むデータなど)ので置換などを行う場合は注意が必要.