目次

目次

ZeppelinでAWS BillingのCSVを分析する

松木佑徒
松木佑徒
最終更新日2017/11/27 投稿日2017/11/27

AWS BillingのCSVはそのままでは見にくいのでDBなどに投入する必要があると思いますが、Zeppelinを使用すれば一時テーブルを使用して簡単にSQLで分析を行うことができます。

GUIからSQLを書くだけでグラフの描画まで簡単にできますのでちょっとした分析をしたいときに便利です。

CSVを一時テーブルに読み込む

Zeppelin上ではR言語やPythonでも書けるのですがデフォルトのでScalaで書いてみました。

Scalaは不慣れなので見にくくてすみません。。 力技ですが以下のようなコードでCSVを読み込むことができます。 (CSVファイルはあらかじめ /data/xxxxxxxxxx-aws-billing-csv-2017-10.csv に配置しておきます)

%spark
val all_billing = sc.textFile("/data/xxxxxxxxxx-aws-billing-csv-2017-10.csv")

// ヘッダを除く
val header = all_billing.first()
val header_less_billing = all_billing.filter(row => row != header)

// 変換用の関数を定義
def toStr(s: String): String =
  try { s.replaceAll("\"", "") } catch { case e: Exception => "" }
def toInt(s: String): Int =
  try { s.replaceAll("\"", "").toInt } catch { case e: Exception => 0 }
def toLong(s: String): Long =
  try { s.replaceAll("\"", "").toLong } catch { case e: Exception => 0L }
def toDouble(s: String): Double =
  try { s.replaceAll("\"", "").toDouble } catch { case e: Exception => 0.0 }

// Billingレコードのクラスを定義
case class Record(
    InvoiceID:String,
    PayerAccountId:Long,
    LinkedAccountId:Long,
    RecordType:String,
    RecordID:Integer,
    BillingPeriodStartDate:String,
    BillingPeriodEndDate:String,
    InvoiceDate:String,
    PayerAccountName:String,
    LinkedAccountName:String,
    TaxationAddress:String,
    PayerPONumber:Integer,
    ProductCode:String,
    ProductName:String,
    SellerOfRecord:String,
    UsageType:String,
    Operation:String,
    RateId:Integer,
    ItemDescription:String,
    UsageStartDate:String,
    UsageEndDate:String,
    UsageQuantity:Integer,
    BlendedRate:Integer,
    CurrencyCode:String,
    CostBeforeTax:Double,
    Credits:Double,
    TaxAmount:Double,
    TaxType:String,
    TotalCost:Double
)

// CSVレコードをRecordインスタンスに詰め替え
val records = header_less_billing.map(s=>s.split(",")).map(
    s=>Record(
        toStr(s(0)),
        toLong(s(1)),
        toLong(s(2)),
        toStr(s(3)),
        toInt(s(4)),
        toStr(s(5)),
        toStr(s(6)),
        toStr(s(7)),
        toStr(s(8)),
        toStr(s(9)),
        toStr(s(10)),
        toInt(s(11)),
        toStr(s(12)),
        toStr(s(13)),
        toStr(s(14)),
        toStr(s(15)),
        toStr(s(16)),
        toInt(s(17)),
        toStr(s(18)),
        toStr(s(19)),
        toStr(s(20)),
        toInt(s(21)),
        toInt(s(22)),
        toStr(s(23)),
        toDouble(s(24)),
        toDouble(s(25)),
        toDouble(s(26)),
        toStr(s(27)),
        toDouble(s(28))
    )
)

// 一時テーブルとして保管
records.toDF().registerTempTable("billing")

一時テーブルに対してSQLを実行する

取り込んだデータはテーブルとして扱えるのでSQLを実行できます。

%sql
select *
from billing

UsageType で集計した結果です。 結果は表形式だけでなく簡単なグラフを自動で生成してくれます。

%sql
select UsageType, sum(TotalCost) as cost
from billing
group by UsageType
order by cost

まとめ

分析したいCSVのレコードに合わせてクラスを定義することで他のフォーマットに対しても 同様のことができますのでCSVを分析したいときに使ってみてはいかがでしょうか。

松木佑徒

目次