#背景
職場の方がラズベリーパイで大気やら紫外線やらのデータを収集しています。
今やっているプロジェクトでグラフ描画するのに、そのデータを拝借してサンプルに使おうと思ったら、
途中に変なデータが混じっていたので、整形しないと使えないなーって書いたコードを書き残します。
#こんなデータ
yyyy/mm/dd hh:mm:ss,大気圧(hPa),温度(℃)
で0時から23時59分59秒まで毎秒データを取得
たまーに大気圧データの頭に10が付いているデータが混じっている様子
2018/07/12 00:00:00,1014.44,28.59
2018/07/12 00:00:01,1014.44,28.59
2018/07/12 00:00:02,1014.46,28.62
2018/07/12 00:00:03,1014.45,28.62
2018/07/12 00:00:04,1014.44,28.59
2018/07/12 00:00:05,1014.45,28.62
2018/07/12 00:00:06,101014.45,28.59
2018/07/12 00:00:07,1014.45,28.62
~ 中略 ~
2018/07/12 23:59:58,1006.29,28.66
2018/07/12 23:59:59,1006.28,28.62
#やりたいこと
CSVを読み込んで、必要な加工をして、別名のCSVに出力したい。
- 毎秒は不要なので1分毎のデータを書き出したい。(毎分00秒だけ抽出する)
- 00秒の大気圧データに101014.45みたいな数値が入っていたら1014.45に直してデータを書き出したい。
#完成したコード
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class test{
public static void main(String[] args) {
process("20180712.csv", ":00,","output.csv");
}
public static void process(String read_file, String searchString, String output_file){
try(FileReader fr = new FileReader(read_file);BufferedReader br = new BufferedReader(fr);
FileWriter fw = new FileWriter(output_file);BufferedWriter bw = new BufferedWriter(fw)){
String line;
while ((line = br.readLine()) != null) {
Pattern p = Pattern.compile(searchString);
Matcher m = p.matcher(line);
if (m.find()){
String[] csvArray;
csvArray = line.split(",");
String time = csvArray[0];
float press = Float.parseFloat(csvArray[1])%10000;
String pressure = String.format("%.2f", press);
String temperature = csvArray[2];
String outputLine = String.join(",",time,pressure,temperature);
bw.write(outputLine);
bw.newLine();
}else{
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
#** やっていること **
processに読込むファイル名 , 検索文字 , 出力ファイル名 の3つの引数を渡してます。
process("20180712.csv", ":00,","output.csv");
❶ Pattern と Matcher を使用して 0秒(":00,") の行を検索
❷ 00秒を含む行が見つかったら、Stringの配列(csvArray)に , (カンマ) でsplitして入れる
❸ 大気圧データ(csvArray[1])は小数なのでString型からfloat型に変換する
※ついでに10000で割った 余りを値に設定する。101014.45を10000で割ると余りは1014.45
❹ float型のデータを再度String型に変換する
※ついでに小数第二位以下を四捨五入して値に設定する。
❺ 各配列の値を, (カンマ) で繋げる
❻ 1行出力して改行する
❶~❻までを読込むファイルの行数分繰り返す
#** メモ **
######検索するのに使った Pattern と Matcher
MatcherはPattern.matcher()メソッドに文字列を渡して作成できる。
マッチ判定の結果がtrueかfalseで返される。
Pattern pattern = Pattern.compile("う"); //検索したい文字列 "う" を設定する Pattern を作成
Matcher matcher = pattern.matcher("あいうえお"); //検索対象の文字列 "あいうえお" を検索対象にするよっていう matcher を作成
matcher.find() // 部分的にマッチするかの判定
matcher.lookingAt() // 先頭からマッチするかの判定
matcher.matches() // 完全にマッチするかの判定
######関数電卓
はじめてWindowsの標準電卓以外の電卓機能を使ったのでメモ
101014.45を10000で割ったときのあまりを求める時
101014.45 Mod 10000 = 1014.45