ワンライナーで少子化を体感しよう

36
ススススススススス ススススススススススス スススス CyberZ スス スス

Upload: nagao-kazuma

Post on 13-Apr-2017

348 views

Category:

Engineering


0 download

TRANSCRIPT

Page 1: ワンライナーで少子化を体感しよう

スキルウェンズデーワンライナーで少子化を体感しよう

CyberZ  長尾 和真

Page 2: ワンライナーで少子化を体感しよう

自己紹介• 名前:長尾 和真• 言語: java• 趣味:ニコ動、カラオケ、飲み会• 好きな本:「嫌われる勇気」、「何者」

Page 3: ワンライナーで少子化を体感しよう

大学では何をやってたの?• 専攻:経済学• 研究室:人口論高齢化、少子化、過疎化、貧困、女性の地位、平均寿命、生涯未婚率、離婚率、出生率、死亡率、人口増加… etc

Page 4: ワンライナーで少子化を体感しよう

大学では何をやってたの?• 専攻:経済学• 研究室:人口論高齢化、少子化、過疎化、貧困、女性の地位、平均寿命、生涯未婚率、離婚率、出生率、死亡率、人口増加… etc

Page 5: ワンライナーで少子化を体感しよう

本題日本の出生率をワンライナーで計算してみましょう!

Excel でやったほうがいい

Page 6: ワンライナーで少子化を体感しよう

予備知識少子化合計特殊出生率が長期間に渡って 2.1 を大きく下回ること 合計特殊出生率1 人の女性が 15 歳から 49 歳までの間に何人子供を生んでいるかという水準を表す数値

n 歳の女性産んだ子供の数n 歳の女性の数Σ

n=15

45

Page 7: ワンライナーで少子化を体感しよう

使うコマンド一覧cat – ファイルの出力cut – フィールド単位で切り出すtr – 区切り文字の整形、特定の文字列の削除grep – 該当箇所の抽出awk – データの抽出・集計join – データの結合

Page 8: ワンライナーで少子化を体感しよう

cut コマンド特定のデータを切り出すコマンド今回使うオプション  -d  区切り文字を指定する  -f  切り出すフィールドを指定する  (-c  切り出す文字のインデックスを指定する )

Page 9: ワンライナーで少子化を体感しよう

cut コマンド 例

Page 10: ワンライナーで少子化を体感しよう

tr コマンド• 文字置換、 文字削除、連続した文字を潰す今回使うオプション  -d  特定の文字を消去する  -s  特定の連続した文字を押しつぶす

Page 11: ワンライナーで少子化を体感しよう

tr コマンド例

Page 12: ワンライナーで少子化を体感しよう

grep コマンド行単位で検索を行うコマンド• 今回使うオプション  -E  正規表現で検索する

Page 13: ワンライナーで少子化を体感しよう

awk コマンド行単位で様々な処理を行うコマンド

処理を行う条件 { 何か処理 } が基本 『 { } 』の中はわりと自由に書ける-  各フィールドは ${number} で参照可能 - 連想配列- for, if ,while- 便利な組み込み関数 ( gsub, toupper, substr  

etc)

Page 14: ワンライナーで少子化を体感しよう

awk コマンド例行単位で様々な処理をするコマンド

$1 $2 $3

$0

組み込み変数NF

NR

処理している行のフィールド数処理している行番号

Page 15: ワンライナーで少子化を体感しよう

join コマンド2 つのファイルを結合するコマンド今回使うオプション  -t  列の区切り文字を指定  -j   2 つのファイルを結合する列を指定  -1   1 つ目のファイルの結合に使う列を指定  -2   2 つ目のファイルの結合に使う列を指定

Page 16: ワンライナーで少子化を体感しよう

join コマンド例

Page 17: ワンライナーで少子化を体感しよう

方針• 総務省・厚生労働省から統計データ (Excel)をダウンロードする• txt ファイルに copy & paste ( ここまで

DONE)( women.txt, children.txt に保存してある想定 )

• コマンドを組み合わせてほしいデータを抽出• awk で計算する

Page 18: ワンライナーで少子化を体感しよう

理想型のデータ構造年齢別に見た女性の数( 年代 ) (15-19 歳の女性の数 ) (20-24 歳の女性の数 ) … (45-49 の女性の数 )

例1995 4172183 4853773 4336016 4012606 3876412 4478720 52900312000 3654181 4114218 4825032 4339792 4018579 3876048 44482362005 3194950 3595776 4081498 4821592 4332994 4015126 38583612010 2954128 3160193 3601978 4120486 4836227 4341490 4005147

母親の年齢別に見た出生数( 年代 ) (15-19 歳の母親が産んだ子供の数 ) (20-24) … (45-49 の母親が産んだ子供の数 )

1995 16112 193514 492714 371773 100053 12472 4142000 19772 161361 470833 396901 126409 14848 4022005 16573 128135 339328 404700 153440 19750 5982010 13546 110956 306910 384385 220101 34609 792

Page 19: ワンライナーで少子化を体感しよう

理想型のデータ構造=> 2 つのファイルを join コマンドで結合!

( 年代 ) (15-19 歳の女性の数 ) … (45-49 の女性の数 )   (15-19 歳の出産数 ) … (45-49 歳の出産数 )1995 4172183 ... 5290031 16112 … 4142000 3654181 ... 4448236 19772 ... 4022005 3194950 ... 3858361 16573 ... 5982010 2954128 ... 4005147 13546 ... 792

=> 1 行にまとめて awk で計算!

Page 20: ワンライナーで少子化を体感しよう

整形

とりあえず grep してみる

Page 21: ワンライナーで少子化を体感しよう

整形

ちょっとすっきり次は・西暦を切り出したい・年齢と女性の人口の部分を切り出したい (cut コマンド )

西暦の部分のフィールドを年齢の部分を合わせたい cut –d” ” –f1,2,5  で切り抜きたい 整形が必要 ( スペース数 )- 赤をフィールド 1,- 青をフィールド 2, - オレンジをフィール 5 に

Page 22: ワンライナーで少子化を体感しよう

整形

西暦を出して「〜」をスペースに変換

このままだとスペースが重なっているため、 cut コマンドでどのフィールドを切り出すべきか分かりづらい=> スペースの重なりをなくして、赤が field1 になるように

Page 23: ワンライナーで少子化を体感しよう

整形

大分すっきり欲しい部分が大分みえてきました

cut コマンドを走らせましょう!

Page 24: ワンライナーで少子化を体感しよう

整形

だいぶすっきりしかし、ファイルの下には注意書きなどいらない文字列がある=> なくすために grep で整形数字で始まり、「 ) 」 を含まないものを抽出すればよさそう同時に 「 , 」も取り除きましょう grep と  tr  でいける!

Page 25: ワンライナーで少子化を体感しよう

整形

かなり整ってきました次は該当年齢と西暦のみを抽出していきます。- 西暦と年齢の両方を出力- 今までと違って数字 ( 年齢 ) の大小を比較する必要がawk でいけそう- フィールドが 2 つ以下の場合 { フィールド 1 を出力 }- フィールドが 2 つより多い場合 && フィールド 2が 19以上 49 未満のとき { フィールド 3 を出力 }

みたいなやってみましょう

Page 26: ワンライナーで少子化を体感しよう

整形

必要なデータが取り出せました!!しかし困りましたあとは join するために年号 (15-19 の女性人口 ) … (45−49 の女性人口 )という形にしなければいけない。。 西暦を西暦とわかるように何かしらの文字を残しておけば   tr コマンドでいけそうですね!やってみましょう

Page 27: ワンライナーで少子化を体感しよう

整形

西暦の前に「 _ 」を仕込んでおいてtr で改行をスペースに変換(全てスペース区切りで一行になる )tr で「 _ 」を改行に変換 年号ごとに改行される!というわけで女性の人数は出せましたね!

Page 28: ワンライナーで少子化を体感しよう

整形

同じようにして子供の人数を抽出します(雑) 女性のデータ : num_w.txt子供のデータ : num_c.txt

join していきます

Page 29: ワンライナーで少子化を体感しよう

join

西暦 女性の数 子供の数

女性の数の 7 つ後ろのフィールドに対応する子供の数がある= $i と $(i+7) で計算できる

Page 30: ワンライナーで少子化を体感しよう

awk で計算

Page 31: ワンライナーで少子化を体感しよう

でました!

Page 32: ワンライナーで少子化を体感しよう

でましたね!!

・・・あれ でも ワンライナーじゃなくない?

Page 33: ワンライナーで少子化を体感しよう

bash のプロセス置換機能を利用するコマンドを入力対象として利用出来るつまりこんな感じjoin -j1 –t” “ < ( 女性の算出コマンド ) <( 子供の算出コマンド ) | awk ‘{ 計算 }’

ワンライナーでできないこともない!

Page 34: ワンライナーで少子化を体感しよう

最終的なコマンド join -t " " -j1 <(cat women.txt | grep -E "〜 | 年 " | tr " 年 " "\n" | tr "〜 " " " | tr -s " " | cut -d" " -f2- | cut -d" " -f1,2,5 | grep -E "^[0-9][^\)]+"| tr -d "," | awk 'NF<=2{print "_"$1} NF>2&&$2>=19&&$2<=49{print $3}' | tr "\n" " " | tr "_" "\n") <(cat children.txt | tr -s " " | tr -d "," | awk '$3>1000000{print}' | cut -d " " -f2-10 | grep -E ^[0-9]{4} | cut -d" " -f1,3-) | awk '{ tfr = 0; for ( i = 2; i < 2 + 7; i++ ) { tfr += $(i+7) * 5 / $i; } print $1,tfr; }’

可読性のかけらもないですね

Page 35: ワンライナーで少子化を体感しよう

ご清聴ありがとうございました

Page 36: ワンライナーで少子化を体感しよう

参考文献