search
LoginSignup
0

posted at

独自形式の実験データファイルをpandasで読み込む

公式ドキュメントをちゃんと読めばわかる話だったのだが,探し方が悪くなかなか見つからなかったので備忘録としてまとめる.

実験データを読み込む

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_tableread_csvはデフォルト引数が違う以外は同じ動作をする(はず)のでどちらでも良い.テーブルデータなのでread_tableの方がわかりやすい気もする.
※2 このデータはXRDの測定データ.

参考: pandasで#行を無視して読み込む

文字列オブジェクトを直接読み込む

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は意外とコーナーケースがある(クォーテーションや区切り文字を含むデータなど)ので置換などを行う場合は注意が必要.

参考: pd.read_csv() でコメントアウトの行を読み込まない

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
0