読者です 読者をやめる 読者になる 読者になる

uyamazakのブログ

仕事中の問題と解決メモ。PythonとGoogle Cloudがメイン。bizoceanで新規事業の企画と開発担当。 BigQueryを使ったビッグデータ収集・解析・リアルタイム処理プロジェクト進行中 https://github.com/uyamazak/oceanus

Google Cloud Datalabでよく使う自作スニペット

bizoceanのデータ収集、解析プロジェクトoceanusで、1ヶ月ほど社内データをいじってみて、できてきたスニペットをまとめてみる。

普通のサービス開発時と違って雑になりがち。

主に文字列の変数にしてformatでSQLにぶち込んで使う。

日付の文字列

昨日今日、何日前などはよく使うし、手で変えるのがめんどいので変数にしておく

from datetime import date, timedelta

JST_TODAY  = date.today() +  timedelta(hours=9)
TODAY = JST_TODAY.strftime('%Y-%m-%d')
YESTERDAY = (JST_TODAY - timedelta(1)).strftime('%Y-%m-%d')
SEVEN_DAYS_AGO = (JST_TODAY - timedelta(8)).strftime('%Y-%m-%d')
A_MONTH_AGO = (JST_TODAY - timedelta(31)).strftime('%Y-%m-%d')
THREE_MONTH_AGO = (JST_TODAY - timedelta(90)).strftime('%Y-%m-%d')
print("更新日:" + TODAY)
# A_MONTH_AGO
# TODAY
DATE_PARAMETERS = {"JST_TODAY":JST_TODAY,
                   "TODAY": TODAY,
                   "YESTERDAY": YESTERDAY,
                   "SEVEN_DAYS_AGO": SEVEN_DAYS_AGO,
                   "A_MONTH_AGO": A_MONTH_AGO,
                   "THREE_MONTH_AGO": THREE_MONTH_AGO}


最後のDATE_PARAMETERSはformat()にばらしていれる

query = """
SELECT
  dt
FROM
  [sample_table]
WHERE
  dt > TIMESTAMP("{TODAY}")

""".format(**DATE_PARAMETERS)


SQL文はトリプルクォーテーションで作って、format関数で置換している。

テーブル名

特にTABLE_DATE_RANGEは毎回書くのが面倒。

作成中は1日にして、完成したら30日に伸ばすなど期間指定は一箇所でできるようにする

OCEANUS_FROM = A_MONTH_AGO
OCEANUS_TO =  YESTERDAY
OCEANUS_TABLE_PREFIX = "[oceanus-sample:sample_table]"

OCEANUS_TABLE = """
(
  SELECT 
    STRFTIME_UTC_USEC(DATE_ADD(TIMESTAMP(dt),+9,"HOUR"), "%m/%d-%a") as dt,
  FROM TABLE_DATE_RANGE(
    {OCEANUS_TABLE_PREFIX}, 
    TIMESTAMP('{OCEANUS_FROM}'), 
    TIMESTAMP('{OCEANUS_TO}')
  )
)""".format(OCEANUS_TABLE_PREFIX=OCEANUS_TABLE_PREFIX, 
            OCEANUS_FROM=OCEANUS_FROM, 
            OCEANUS_TO=OCEANUS_TO)


コードが長いと見づらい&コードに興味ない人に見せるときよう

github.com

%%html
<script>
  $('.container').css("width","100%");
  var code_show=true; //true -> hide code at first
  function code_toggle() {
    $('div.prompt').hide(); // always hide prompt
    if (code_show){
      $('div.input').hide();
    } else {
      $('div.input').show();
    }
    code_show = !code_show
  }
  $( document ).ready(code_toggle);
</script>
<a href="javascript:code_toggle()">
[Show Code]
</a>

dataframe関連

# 時系列で一週間ごと(というか7つごとに)にラベルを出す
def xticks_week(index):
  return [i for j, i in enumerate(index) if j % 7 == 0]
# 指定した数ごとに〃
def xticks_every(index, count):
  return [i for j, i in enumerate(index) if j % count == 0]

plot時の引数で使う

new_member_gender_df.plot(figsize=(22,5), x="date", stacked=True, xticks=xticks_every(new_member_gender_df.index,2))

# 1列目のキー以外の数値を割合に変換
def convert_ratio(values):
#print values
new_values = []
for val in values:
array = [val[0]]
sum_v = float(sum(val[1:]))
for v in val[1:]:
array.append(float(v)/sum_v * 100)
new_values.append(array)
return new_values
|

こんな1列目がキー、その他の列を足すと100%になるデータで

new_member_gender_ratio
date	male	female	other
0	09/10-Sat	492	232	47
1	09/11-Sun	510	223	57
2	09/12-Mon	886	469	94
new_member_gender_ratio = convert_ratio(new_member_gender_df.values)
new_member_gender_ratio_df = pd.DataFrame(new_member_gender_ratio, columns=new_member_gender_df.columns)
new_member_gender_ratio_df

こうなる

	date	male	female	other
0	09/10-Sat	63.813230	30.090791	6.095979
1	09/11-Sun	64.556962	28.227848	7.215190
2	09/12-Mon	61.145618	32.367150	6.487233