古川制御日記

佐賀県武雄市の組み込み開発屋ブログ

MATLABで日時列があるcsv読み込み

例えば以下のcsvデータがあった場合

timestamp,value
2021/06/22-13:46:13,10.425000
2021/06/22-13:46:13,10.425000
2021/06/22-13:46:14,10.425000
2021/06/22-13:46:14,10.425000

detectImportOptionsを使うことで

opts = detectImportOptions('test.csv')

readtable()実行時にデフォルトでどのように解釈されるのかわかる。

opts = 
  DelimitedTextImportOptions のプロパティ:
   形式 プロパティ:
                    Delimiter: {'/'}
                   Whitespace: '\b\t '

ただしこういうふうにDelimiterを'/'と誤検出することがある、 この場合、引数としてプロパティ値を与えることで部分的に正すことができる。

>> opts = detectImportOptions('test.csv', 'Delimiter', ',')
opts = 
  DelimitedTextImportOptions のプロパティ:
   形式 プロパティ:
                    Delimiter: {','}
~~ 略 ~~
   変数のインポート プロパティ:
                VariableNames: {'timestamp', 'value'}
                VariableTypes: {'char', 'double'}
        SelectedVariableNames: {'timestamp', 'value'}
              VariableOptions: Show all 2 VariableOptions 
    Access VariableOptions sub-properties using setvaropts/getvaropts
           VariableNamingRule: 'modify'

これでもまだ,timestamp列をただの'char'だと認識しているため、日時であることを伝える必要がある。

opts = setvartype(opts, 'timestamp', 'datetime')

その上で読み出す

test = readtable('test.csv', opts);
警告: 1 つ以上の変数を datetime に変換できません。DatetimeVariableImportOptions で正しい InputFormat プロパティと
DatetimeLocale プロパティを指定してください。 

文句を言われ、test変数の中身を見ると意図しないものとなる。

>> test(1:4,:)

ans =

  4×2 table

    timestamp    value 
    _________    ______

       NaT       10.425
       NaT       10.425
       NaT       10.425
       NaT       10.425

このcsvファイルに記述されてる日時書式では正しく'datetime'として解釈してくれないので、書式を伝える必要がある。
現在optsに設定されてる日時書式を確認すると、

>> getvaropts(opts ,'timestamp')
ans =
  DatetimeVariableImportOptions のプロパティ:
   Variable Properties:
              Name: 'timestamp'
              Type: 'datetime'
         FillValue: NaT
    TreatAsMissing: {}
         QuoteRule: 'remove'
          Prefixes: {}
          Suffixes: {}
    EmptyFieldRule: 'missing'
   Datetime Options:
    DatetimeFormat: 'default'
    DatetimeLocale: 'ja_JP'
       InputFormat: ''
          TimeZone: ''

未指定。

>> opts = setvaropts(opts, 'timestamp', 'InputFormat', 'yyyy/MM/dd-HH:mm:ss');

>> getvaropts(opts ,'timestamp')

ans = 

  DatetimeVariableImportOptions のプロパティ:

   Variable Properties:
              Name: 'timestamp'
              Type: 'datetime'
         FillValue: NaT
    TreatAsMissing: {}
         QuoteRule: 'remove'
          Prefixes: {}
          Suffixes: {}
    EmptyFieldRule: 'missing'

   Datetime Options:
    DatetimeFormat: 'default'
    DatetimeLocale: 'ja_JP'
       InputFormat: 'yyyy/MM/dd-HH:mm:ss'
          TimeZone: ''

InputFormatが書き換わってることが確認できたので再び、`readtable'を実行

test = readtable('test.csv', opts);
>> test(1:4,:)

ans =

  4×2 table

         timestamp         value 
    ___________________    ______

    2021/06/22_13:46:13    10.425
    2021/06/22_13:46:13    10.425
    2021/06/22_13:46:14    10.425
    2021/06/22_13:46:14    10.425

意図した通りに読めた