Pythonでインポートフィルタを作成

Originのインポートフィルタはインポートするファイルの種類はもちろん、ファイルの何行目までがヘッダ情報になっていて、何行目からがデータ、といったファイルの構造についての設定を保存しておける機能です。インポートフィルタを作成しておくことで、同じ構造のファイルをインポートする際に毎回設定する必要がなくなります。

Origin 2020bまでのOriginでは、コードによるインポートフィルタの作成はOriginCにのみ対応していましたが、Origin 2021以降、Pythonを使用して作成できるようになりました。今回は、Pythonを使ったインポートフィルタの作成についてご紹介します。

インポートウィザードでPythonを利用する

PythonやOriginCを使わずにインポートフィルタを作成する手順についてはこちらをご覧ください。

事前準備

このあとご紹介するサンプルでは、Pythonのパッケージライブラリとして"pandas"を利用します。
サンプルを試したい場合には事前に"pandas"をインストールしてください。

Origin内の埋め込みPythonへのパッケージライブラリのインストール方法は下記リンクをご覧ください。

インストールされているパッケージの確認方法はこちらをご覧ください。

サンプルデータ

ここで使っているサンプルデータは下記リンクからダウンロードできます。

zip

zip(4KB)

メタデータをヘッダ行に保存

インポートフィルタはファイルのヘッダ情報を指定してワークシートのラベル行にインポートすることができます。ここでは、Pythonコードを使ってヘッダ情報を設定してインポートする手順をご紹介します。

  1. ワークブックがアクティブな状態でOriginメニューの データ:ファイルからインポート:インポートウィザード を選択します。
  2. 「データタイプ」で「ユーザ定義」を選択、データソースの右側にある「...」からサンプルデータとしてダウンロードした"F1.dat"を選択し、さらに「ターゲット・ウィンドウ」の「インポートモード」を「シートを新たに作って読み込む」に設定し「進む」をクリックします。
  3. インポートウィザード-データソースとターゲット
  4. 「Python」のラジオボタンを選択し、下記コードを入力し、「進む」をクリックします。
  5. import originpro as op
    import pandas as pd
    import os
     	
        # インポートする関数を作成 
    def read_file(file): 
        # アクティブなワークシートの名前を変数wksに代入 
        wks = op.find_sheet()
        
        with open(file, 'r') as f:        
        # ワークシートのヘッダにユーザパラメータ行を追加し、
    	# ファイルの最初の4行にあるメタデータをユーザパラメータ行に入れます
            for i in range(4):
                line = f.readline()
                ll = line.split(":")
                wks.set_label("A",ll[1],ll[0])
    			
            # 1行スキップ
            line = f.readline() 
            
            # ロングネーム行を読み込み
            line = f.readline()
            cols = line.split() 
            
            # 単位行を読み込み
            line = f.readline()
            wks.set_labels([line], 'U')
            
            # データを読み込み
            rows = []
            for line in f.readlines():
                rows.append(line.split())
     
        df = pd.DataFrame(data=rows, columns=cols)
        
        # ワークシートにデータを保存
        wks.from_df(df)
        
        # 列属性を設定
        wks.cols_axis('XYE') 
        
        # ファイル名を使ってシート名を指定
        wks.name=os.path.basename(file)
     
     
    # Originのインポートフィルタで選択したファイル名はLabTalkの変数に"fname$"に保管
    # これをPythonの変数に代入して参照
    # 指定時はLabTalkの変数名に'$'は不要
    fname = op.get_lt_str('fname')
    data = read_file(fname)
    インポートウィザード-ユーザ定義フィルタ
  6. 作成したフィルタを保存するには「フィルタを保存する」にチェックを入れて、「ユーザファイルフォルダに保存」を選択し、「ファイル名」を入力します。
  7. インポートウィザード-フィルタの保存
  8. 「完了」ボタンを押すとダイアログが終了し、作成したインポートフィルタを使ったインポートが実行されます。
  9. インポート結果

補足:作成したインポートフィルタの利用1

インポートフィルタの作成時に設定した「該当ファイル」の形式にあったファイルをOriginへドラッグアンドドロップすると作成したインポートフィルタを使ってファイルがインポートされます。「該当ファイル」を"*.dat"にするとdat形式のファイル全てで作成したインポートフィルタを使用します。
"*"はワイルドカードというOrigin内のいくつかの設定項目で使用できる記号で他には"?"が利用できます。"*"は任意の長さの文字列を表し、"?"は任意の1文字を表します。
(後述する正規表現とは意味が異なっておりますのでご注意ください。)

例えば、"F*.dat"とすれば"F"から始まるdat形式のファイルで作成したインポートフィルタが使用されます。

また、「該当ファイル」の形式に当てはまるインポートフィルタが複数ある場合は、どのインポートフィルタを使用するかを選択するダイアログが表示されます。

インポートフィルタ選択ダイアログ

補足:作成したインポートフィルタの利用2

保存したインポートフィルタを他のPCでも使う、他のユーザと共有する際には、.oif形式の保存したインポートフィルタをコピー、他のPCのOriginドラッグアンドドロップしてください。
「ユーザファイルフォルダに保存」を選択してインポートフィルタを作成した場合、Originメニューの ヘルプ:フォルダを開く:ユーザファイルフォルダ を選択し、"Filters"フォルダに移動しますと作成したインポートフィルタがありますのでこれをコピーしてご利用ください。

インポートフィルタをコピー

日付・時間データをインポート

日付・時間データの形式を指定してインポートしたい場合には、pandasのDataFrameにデータを入れたあと、データ形式を指定しておくことでOriginへのインポート時に自動的にDataFrameでのデータ形式を参照してOrigin上の列フォーマットにも反映されます。

  1. ワークブックがアクティブな状態でOriginメニューの データ:ファイルからインポート:インポートウィザード を選択します。
  2. 「データタイプ」で「ユーザ定義」を選択、データソースの右側にある「...」からサンプルデータとしてダウンロードした"3-15-2020.log"を選択し、さらに「ターゲット・ウィンドウ」の「インポートモード」を「シートを新たに作って読み込む」に設定し「進む」をクリックします。
  3. インポートウィザード-データソースとターゲット
  4. 「Python」のラジオボタンを選択し、下記コードを入力し、「進む」をクリックします。
  5. import originpro as op
    import pandas as pd
    import re
    
    def read_file(file):
        # 行を3つのグループに分けるための正規表現
        p = re.compile(r'(\S+)\s+(\S+)\s+(.*)')
        # リストを用意して、そこに 日付・時間・メッセージ に分けて各行のデータを追加
        rows = []
        with open(file, 'r') as f:
            line = f.readline()
            while line:
                m = p.match(line)
                if m:
                    rows.append(m.groups())
                line = f.readline()
        # rowsに入ったデータをpandasのDataFrame形式に変換
        df = pd.DataFrame(data=rows, columns=['Date', 'Time', 'Message'])
    	# 'Date'に入れたデータのフォーマットを指定
        df['Date'] = pd.to_datetime(df['Date'], format='%m/%d/%y')
    	# 'Time'に入れたデータのフォーマットを指定
        df['Time'] = pd.to_datetime(df['Time'], format='%H:%M:%S').dt.time
        return df
    
    
    # Originのインポートフィルタによって選択されたファイル名はLabTalkの変数"fname$"に保管
    # これをPythonの変数に代入
    # 指定時はLabTalkの変数名に'$'は不要
    fname = op.get_lt_str('fname')
    
    # ファイルを読み込みpandasのDataFrameに代入
    data = read_file(fname)
    
    # wks変数にアクティブなワークシート名を代入
    wks = op.find_sheet()
    
    # DataFrameのデータをシートの1列目から追加
    # DataFrameの列ラベルはワークシートの列ロングネーム
    # Originは自動的にDataFrameのデータ形式をもとにワークシートの各列の列フォーマットを設定
    wks.from_df(data)
    インポートウィザード-ユーザ定義フィルタ
  6. 作成したフィルタを保存するには「フィルタを保存する」にチェックを入れて、「ユーザファイルフォルダ」に保存を選択し、「ファイル名」を入力します。
  7. インポートウィザード-フィルタの保存
  8. 「完了」ボタンを押すとダイアログが終了し、作成したインポートフィルタを使ったインポートが実行されます。
  9. インポート結果

補足:正規表現について

コード6行目で使用している"\S+"や".*"は正規表現というものです。正規表現では「何文字の文字列」や「"ab"という文字が含まれる文字列」など、文字列をパターンとして1つの形式で表せるため、パターンに該当する文字列を探す場合に便利です。
ここで使っている"\s"は「任意の空白文字」を、"\S"は「任意の空白文字以外」を表します。
"+"は「1回以上の繰り返し」を表しますので、"\S+"で「任意の空白文字以外が1回以上繰り返された文字列」を表します。
"."は「任意の1文字」、"*"は「0回以上の繰り返し」を表しますので、".*"で「任意の文字が0回以上繰り返された文字列」となります。

"originpro"パッケージに導入されているクラスの一覧やリファレンスは下記リンクから確認できます。

Python連載企画一覧ページ

page_top_icon