所感

一年ぶりくらいに考えをまとめるべく書く.
最近はどちらかと言うとアプリ開発だとかということよりも, 研究開発に寄っていて幸運にもpixivという会社が僕を雇ってくれたこともあり, pixiv社でオープンソースを開発している.
具体的にはJpegを見た目の美しさを保ったままでより圧縮するアルゴリズムを開発するお仕事であり, 中々未知な部分が多いのではあるが, なんとか取り組んで行きたい課題だ. もうすぐしたらβ版くらいまでは出せるのではないだろうか.


...


最近の悩みは院進についてである.
来年以降自然言語処理についての研究をしたいと考えていて, NAIST, 京都大学, 東京工業大学と三つの大学をまわった.
個人的には東京工業大学京都大学に惹かれる部分を感じたのだが, 東京工業大学には入試の都合上, A日程とB日程という二つの日程に分かれ, A日程は事実上内部生のための推薦制度のようなものなのだが, これで定員の半数を受け入れることを院試説明会で初めて聞いた(僕はせいぜい一割か二割程度であろうと思っていたので寝耳に水だったが...)
また、志望する研究室はかなり人気になることが期待されるため, これではA日程で席が埋まり, B日程に席は一つも回ってこない可能性が考えられ, 仮にB日程を一位で通過したとしても, 諦めざるを得ない..という制度になりえてしまうのだ. 私の成績だとB日程に回されることは確実であり, 最初から勝ち目のない戦いなのかもしれない.

京都大学はというと, 決してそんなことはなく純粋にペーパーの成績で振り分けられるようである.
ただ, 僕が志望する研究室はおそらく第一人気となることはないと思われるが, それでも自然言語処理ができる研究室で有名であるため, おそらく合格者の中でも中位程度の成績を収めなければならないだろう.
合格したとしてもそれが最下位であったなら。 おそらくそれは辞退をする他選択肢はないだろう.


...


結局どこかに賭けるしかない.
最終的にはそこなのであるが, バンディットアルゴリズムを人生に適用できるほど僕はできていない.
落ちてしまったらどうしようかとか, やはりNLP(というかAIと言われる部門全体?)は人気であり, そう簡単にはいかないだろう...。
研究生として受け入れてもらえるか? はたまた, 落ちてしまった時点で就活をするのか?
仮に就職できたとしても, 僕はMachine Learningを続けられるのか? ...etc.

悩みは渦になってぐるぐると何度も頭の中を反芻する.


ステレオポニー - ツキアカリのミチシルベ

苦しいし, 険しい. 外部院進を誰もが敬遠する理由がわかるし, Hotな分野のせいというのもあるのかもしれない..
それでももうそろそろ賭けるべきを決めて、そこに一点注力をさせないことには希望の光は見えてこない.

そういうタイミングなのかもしれない.

大学二年生でweb系を1からサービスを立ち上げたりするまでに読んだ本

大学三年生になりました. 明日からまた学校なので, 2年生に読んだ本とかまとめてみようと思う.
ちなみに大学2年の段階ではweb系は全くで, 1年の12月くらいにC言語の本を読んだくらいの能力しかなかったけど,
それでも4~8月でサービスをデプロイするところまでは行けたので, 勉強することは多いけど気合いがあればなんとかなると思う.

4~6月

自分はロック音楽が好きで,ART-SCHOOLというバンドが好きなのだが,周りに同じような人がいなかった.
でも,周りの聞いているアーティストとかみてるとこっちも好きになってくれてもいい潜在的なファン(?)がいるように思えた..
ので,そんなサイトを作りたいなーとかちょっと考えたのがきっかけ.

HTML/CSSとかからスタートした.

作りながら学ぶ HTML/CSSデザインの教科書

作りながら学ぶ HTML/CSSデザインの教科書

これ結構分厚かったけど, 一からサイト作るって感じで分かりやすかった.
jQueryとかもちょろっと乗ってて次何をやればいいかとかも明確になった.
同時進行でPHPもスタートしていて,
いきなりはじめるPHP~ワクワク・ドキドキの入門教室~

いきなりはじめるPHP~ワクワク・ドキドキの入門教室~

気づけばプロ並みPHP 改訂版--ゼロから作れる人になる!

気づけばプロ並みPHP 改訂版--ゼロから作れる人になる!

この辺りも読んだ. これも一から作る感じでモチベーションは高く望めた(ただLAMPのバージョンがちと古すぎた気が..)
ショッピングカートの方は変数がたくさん出てきて少し混乱するところもあった気もする.

この辺でどうやら装飾をするならJavaScriptっていうのをやらないといけないなと気づいて,

これを読んで, なんかそのままこれも読んだ. この段階だと多分読まなくていい本なんだけど,
でも後々いろいろJSを触るときに今でも役立っているから読んでよかったと思う.
(JSのオブジェクト指向とかはちょっと違うからなぁと)
それで一応jQueryも読んだ.
改訂版 Webデザイナーのための jQuery入門

改訂版 Webデザイナーのための jQuery入門

わかりやすかった.

さて, この辺でPHPでサービスを作ろう!とはなったのだけれど, 実際にどこから書けばいいのか分からなかった.
調べていくうちにどうやらサービスを作るときは1から作るというより,フレームワークを利用するらしい.
CakePHPの本を読んだのだけれど, MVCがさっぱりな状態からだったので挫折. もっとわかりやすい本ないかなあと調べていたところ,

はじめてのフレームワークとしてのFuelPHP 改訂版

はじめてのフレームワークとしてのFuelPHP 改訂版

これが分かりやすかった.
一応パーフェクトPHPとかも文法を補うべく読んでた.
パーフェクトPHP (PERFECT SERIES 3)

パーフェクトPHP (PERFECT SERIES 3)

7月

なぜかリクナビに登録して, 福岡のベンチャー企業でペーペーなのにインターンさせていただくことに.
(今思うとよく通ったな..), PHPで働くのかと思っていると,その会社はRubyだったので,急遽Rubyを勉強した.
Rubyは書きやすく分かりやすかった.

作りながら学ぶRuby入門 第2版

作りながら学ぶRuby入門 第2版

Ruby, Web開発とくればRuby on Rails!となって, Railsをメンターの方に教えてもらいながら,conpassみたいなサイトを作った.
パーフェクト Ruby on Rails

パーフェクト Ruby on Rails

これだけだとアレだったので, 自分でもう一冊読んでた.
改訂3版 基礎 Ruby on Rails 基礎シリーズ

改訂3版 基礎 Ruby on Rails 基礎シリーズ

こっちの方が初めてなら分かりやすい.

この頃に自作したいアプリは, 機械学習っていうのが必要だ..!って気づいて,
機械学習ならPythonやれみたいな感じだったので,Pythonをはじめた. これがいい言語で, 今もメインで使っている.

Pythonスタートブック

Pythonスタートブック

入門 Python 3

入門 Python 3

ちなみに, はてなインターンは行けずだった。初心者だから当然と言えば当然..
この時に一回だけはてなのエンジニアさんとお話しできる機会があり, 「Web系と言えど基礎が大切」という話を伺った
その助言は今もずっと残っている

8月

ちょうどよく夏休みで, アプリの作り方もわかってきて, この夏に機械学習でロジック部分を完成させてアプリを出してやろうと考えていた.
まず数学を一年レベルはしっかり固めようということで,

微積(ラグランジュの未定乗数法は絶対にいる)

微分積分 (理工系の数学入門コース 1)

微分積分 (理工系の数学入門コース 1)

線形代数
プログラミングのための線形代数

プログラミングのための線形代数

統計学

そして機械学習. この本面白かった, おすすめ.

ITエンジニアのための機械学習理論入門

ITエンジニアのための機械学習理論入門

k-meansやら協調フィルタリングを駆使して, 自分なりに作ってインターンで発表した.
(今見るとなんでそのモデリングなのか不適切だが)高評価だったので嬉しかった.

www.slideshare.net


これは別のところで発表した資料.

9月

アプリ公開. herokuを利用した.

MusicLanguage

アーティストを打ったらおすすめアーティストをレコメンドしてくれるというもの.
はじめてのアプリということになりそう. 正直この月のことはあまり記憶に残っていない..

10月

大学の後期が始まり, 機械学習にのめり込むようになり, 最適化数学を勉強した.

これなら分かる最適化数学―基礎原理から計算手法まで

これなら分かる最適化数学―基礎原理から計算手法まで

この本は程よく数式があり, 具体例豊富でわかりやすく, とてもよかった.
Deep Learningにも手を出し始めたような気がする..。

定番中の定番.

基礎的な技術が身に付けたいと思い, 競技プログラミングを始めた.
あり本をICPCサークルの人と一緒に読み解いたりした.

このあたりでインターンをやめた
もっと学問として情報科学/計算機科学, 機械学習と向き合いたいと思ったからである

11~12月

あまり覚えていないが, DeepLearningにかなり傾倒していくようになり,
Chainerを利用してデータをぶち込んでぐるぐる回したり, あといろんなDeepLearningを試していたりした

Chainerによる実践深層学習

Chainerによる実践深層学習

実装 ディープラーニング

実装 ディープラーニング

Chainerはバージョンアップで内容が古くなってはいるが, 雰囲気を掴むにはいいかもしれない.

1~3月

親と相談して, 15ヶ月食費を抜きにしてDeepLearning用PCを購入することに成功した.
これにより, ようやくまともにビッグデータをぶちこめるようになった. 購入したのはGTX1070がついたBTOのPC. Ubuntu+Chainer+GPUのセットアップで苦労した.
この頃から, PRMLをしっかり読もう, もうそれしかないなと思ってPRMLを購入. この頃はとりあえず歯を食いしばって頑張っていたが, 最近になってようやくベイズ的考え方が身についてきたと思う. もうちょっと数学をやる必要は感じているが..

パターン認識と機械学習 上

パターン認識と機械学習 上

2月末にLINE BOT AWARDS用に「顔をみてそこから髪型をおすすめするアプリ」をDeepLearningで作り, コンペに提出した.
ファイナリストには残らなかったが, そのあとの後夜祭(4月)でLINE本社で発表する機会をもらえて嬉しかった.交通費も出たのはありがたい..
東京は楽しかったし, きている人のエンジニアのレベルが高いのが頭に残っている. LINEのインターンもいけたらいいな.

www.slideshare.net


4月のはブログに別でまとめている.

これからの予定

ニューラルネットワークに限らず, 機械学習/ベイズ推論/確率的プログラミングの基礎を勉強したい.
SICPみたいな本も読んでいきたい.
設計について深く考えたい.
競プロ力あげたい.
アプリ作りたい.

などなど. 基礎技術を勉強しながら手を動かしてアプリやツールも作っていきたいと思う.
OSSに貢献したりもやってみたいなぁ. まだまだこれからなので, どんどん勉強していきたいと思う

numpyについて2

インデキシング, ブロードキャスティングなどについて詳しく見ていく.

基本インデキシング

まず, numpyのデータに変数を与えることは普通の値を渡す状態なのではなく, 参照渡しであることに注意する.
つまり, ひとつのndarrayオブジェクトに変数を複数渡り当てた場合,ひとつの変数から値を変えると他の変数にも影響が出ることになる
これはビューといって, 余計なメモリを生み出さないための方法である.

In [1]: import numpy as np

In [2]: x2d = np.arange(12).reshape(3, 4)

In [3]: x2d
Out[3]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

# ここは, x2d[1, 1:]とも書ける(numpyのみ)
In [4]: a = x2d[1][1:]

In [5]: a
Out[5]: array([5, 6, 7])

In [6]: a[0] = -1

In [7]: a
Out[7]: array([-1,  6,  7])

In [8]: x2d
Out[8]:
array([[ 0,  1,  2,  3],
       [ 4, -1,  6,  7],
       [ 8,  9, 10, 11]])

応用インデキシング

先ほどのように, ビューが生成されるのではなく, コピーが生成される.
このため, メモリの量には気をつける必要がある.(大きいデータを扱うことがメインのため)

In [11]: dat = np.random.rand(2, 3)

In [12]: dat
Out[12]:
array([[ 0.98810811,  0.53605981,  0.80088131],
       [ 0.44439242,  0.4916097 ,  0.07521805]])

In [13]: bmask = dat > 0.5

In [14]: bmask
Out[14]:
array([[ True,  True,  True],
       [False, False, False]], dtype=bool)

In [15]: highd = dat[bmask]

In [16]: highd
Out[16]: array([ 0.98810811,  0.53605981,  0.80088131])

In [17]: highd[0] = 1000

# datには無影響である
In [18]: dat
Out[18]:
array([[ 0.98810811,  0.53605981,  0.80088131],
       [ 0.44439242,  0.4916097 ,  0.07521805]])

In [19]: highd
Out[19]: array([  1.00000000e+03,   5.36059805e-01,   8.00881315e-01])

整数配列でのインデキシングは, リストを渡すことによって可能である

In [24]: nda = np.arange(10)

In [25]: ndb = nda[1:4]

In [26]: ndb
Out[26]: array([1, 2, 3])

In [27]: ndc = nda[[1, 2, 3]]

In [28]: ndc
Out[28]: array([1, 2, 3])

浅いコピー, 深いコピー

numpyには浅いコピーと深いコピーがある.
浅いコピーには参照が渡される. 基本インデキシングはこちらになる.

深いコピーでは, 値が渡されるので, 元々のデータと別物になる.
応用インデキシングで見せた, ブール配列によるインデキシングや, 整数配列によるインデキシングだけでなく,
copy()メソッドや, flatten(一次元にする), a.clip(min, maxを指定し, min以下のものはminへ, max以上のものはmaxへ)などもこちらに属する

ufunc. ユニバーサル関数について

numpyには, map関数として配列の要素のそれぞれにアクセスして特定の処理をして返す関数があり,
ユニバーサル関数と言われる.

In [30]: nda = np.arange(12).reshape(2, 6)

In [31]: nda
Out[31]:
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11]])

In [32]: np.square(nda)
Out[32]:
array([[  0,   1,   4,   9,  16,  25],
       [ 36,  49,  64,  81, 100, 121]])

既存のpythonの関数を, frompyfuncを利用することによってufunc化することもできる

In [34]: hex_array = np.frompyfunc(hex, 1, 1)

In [35]: hex_array((10, 30, 100))
Out[35]: array(['0xa', '0x1e', '0x64'], dtype=object)

ブロードキャスティング

  1. , /, *, -などの計算は, 同じ大きさ同士のものでなければ計算することはできない.

この点を解消してくれるのが, ブロードキャスティングである. これが結構ややこしい(というか, 言葉にするより図に書くべきだと思う).
詳しくは, ここをみてほしい

In [36]: nda = np.arange(24).reshape(4, 3, 2)

In [37]: ndb = np.arange(6).reshape(3, 2)

In [38]: ndc = np.arange(3).reshape(3, 1)

In [39]: nda + ndb - ndc
Out[39]:
array([[[ 0,  2],
        [ 3,  5],
        [ 6,  8]],

       [[ 6,  8],
        [ 9, 11],
        [12, 14]],

       [[12, 14],
        [15, 17],
        [18, 20]],

       [[18, 20],
        [21, 23],
        [24, 26]]])

この例だと, ndaに合わせていく形になり, ndb, ndcの次元を一つ増やして3にする. あいているところは, 今と全く同じベクトル/行列で埋める.
次に大きい軸(z, x, y)ならyで埋めていくと, nbcは(4, 3, 2)の形にまで大きくすることが可能. これにより, (4, 3, 2)を出力の行列として計算することができる. このように, ぴったりと埋まらない場合にブロードキャスティングでエラーが発生する. 例えば, 以下の例である.

In [47]: nda = np.arange(12).reshape(3, 4)

In [48]: ndb = np.arange(4)

In [49]: nda + ndb
Out[49]:
array([[ 0,  2,  4,  6],
       [ 4,  6,  8, 10],
       [ 8, 10, 12, 14]])

In [56]: ndb.reshape(4, 1)
Out[56]:
array([[0],
       [1],
       [2],
       [3]])

In [60]: nda + ndb
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-60-c79787edb196> in <module>()
----> 1 nda + ndb

ValueError: operands could not be broadcast together with shapes (3,4) (4,1)

言葉より図をかいて考えるべきだった..

numpyについて

numpyとは,配列の処理に特化したライブラリで, Pythonのそれよりも高速に処理することができる.
行列演算を簡単に, 高速に行うことができるものであり, 以下の3つの機能を提供している.

(1)ユニバーサル関数
(2)各種関数群
(3)C/C++など, 他言語へのインターフェース

numpyが高速な理由の一つに, RAMのメモリに配列のデータがびっしりと敷き詰められるから, というのがある.
こういう形にすることで, オーバヘッドを抑えることが可能になる.

numpyの組み込みデータ型

組み込みデータ型はたくさんある. 数値を扱うものが大半だが,pythonのオブジェクトを格納するものもある.
これらを使って以下のように書く.

import numpy as np

# 組み込みデータ型(配列)の形で生成する
a = np.complex128([3.2, 4.2+1.09j])

# np.array()で生成し, dtypeに属性を付加することもできる
b = np.array([2234.432, 2.23], dtype=np.single)

多次元配列オブジェクトndarrayについて

Pythonのオブジェクトには, 配列と行列があり, これらを区別して使用しなければならない
たとえば, S = (HVH^T)^-1という行列を計算するとき,以下のような書き方ができる.

# 行列を利用する
import numpy as np

H = np.matrix([[1, 2], [3, 4]])

V = np.matrix([[3, 4], [5, 6]])

S = inv(H * V * H.T)

行列を使えば直感的にかけるが, 配列とごっちゃになる可能性があるので, あまり使用しない.
Python3.5~からは, 配列でも同様に演算できるように @演算子が追加された

import numpy as np

H = np.array([[1, 2], [3, 4]])

V = np.array([[3, 4], [5, 6]])

#従来
S = inv(H.dot(V.dot(H.T)))

#python3.5~
S = inv(H @ V @ H.T)

行列は原則使用しないようにする

ndarrayの生成

pythonのリストやタプルは, そのままnp.array(..)にいれることで, ndarrayオブジェクトに変換できる.
しかし, pythonの配列と違い, いくつか注意点がある

(1) 基本的に同じ型になる
(2) 各次元の要素数が同じ

import numpy as np

mat = [[3, 1, 9], [2, 5, 8], [4, 7, 6]]

array1 = np.array(mat)

その他, arrayだけでなく, arange, one, zerosなどがある.
ones, zerosは1のみ, 0のみの行列を生成する. np.zeros(行, 列)で指定する
arangeはrangeと同じで, (start, end, step)で指定する.

import numpy as np

a = np.zeros(2, 3)

b = np.arange(10, 20, 2)

np.arange(..)は浮動小数点も可能だが, そのときendの値が入ってしまうことには注意しておく.

データ型の指定

(1) Generic Typeによる指定
(2) Pythonの組み込みデータ型に対応する型指定
(3) numpyの組み込みデータ型による指定
(4) 文字コードによる指定

がある. 個人的には(3)が一番使われているような気がする

import numpy as np

dt = np.dtype('float')

# データ型のdtypeオブジェクトを引数に
x = np.array([1.1, 2.1, 3.1], dtype=dt)

# 文字で指定することも可能
x = np.array([1.1, 2.1, 3.1], dtype='float')

numpyの属性

numpyには行列演算のメソッドとは別に, ndarrayの状態を取得する属性群がある.
その中でも, 今回はshapeとndimに焦点を当てる(最初ndimがわからなかった)

import numpy as np

mat = [[3, 1, 9], [2, 5, 8], [4, 7, 6]]

array1 = np.array(mat)

array1.shape
# => (3, 3)

array1.ndim
# => 2

shapeは行*列でタプルで返す関数である.
ndimは, 行列の次元数であり, ベクトルなら1, 行列ならば2, 3次元のテンソルなら3..となっていく.

ndarrayの行列演算

行列演算について, ndarrayの+, -, *, / などの演算は要素同士の演算になることに注意をする.
もし, 行列積を出したいときは, dotか@演算子を使って演算すること.
逆行列演算や, 行列式計算, ランク計算はnumpyで簡単に計算できる

In [32]: np.linalg.inv(mat)
Out[32]:
array([[ 0.23214286, -0.50892857,  0.33035714],
       [-0.17857143,  0.16071429,  0.05357143],
       [ 0.05357143,  0.15178571, -0.11607143]])

In [33]: np.linalg.det(mat)
Out[33]: -112.00000000000006

In [34]: np.linalg.matrix_rank(mat)
Out[34]: 3

インデキシング以降を明日に見ていく.

ファイル入出力のあれこれ(pandas編)

pandasはデータを扱うためのライブラリである.
テキストファイルやらデータベースとの入出力が簡単にできる. 今まで見てきたcsv, excel, hdf5なども取り扱うことができる.
read_...()という形なのでインターフェースもわかりやすい.

pandasが優れているところは, 欠損データだったり意味のないスペースなどのファイルの異常にも対応できるということである.
なお, 大規模計算にはhdf5が最速でデータを読み書きできるのでそちらを利用するほうが良いとのこと.

今回のデータがこれ.

# テストデータ 2016/1/10, encode=utf-8
time;status;高度;速度
0;search;125
0.1;search;1012.5; 128.5;
0.2;lock;1035.3; 130.5987
0.3;lock;1068.365; 135.45
0.4;lock;1090.2; NaN

こんな形でデータがある. これを整形していくことを考える.
今回はutf-8で扱う. 元々の科学技術計算のためのpython入門にはcp932だったがまぁ...そこは.

(1)encodingを確かめる
utf-8なので, 普通に読む.

import pandas as pd

dat = pd.read_csv('data.csv', encoding='utf-8')

一行目を消し, デリミタとして';'を設定する.

dat = pd.read_csv('data.csv', 
                               encoding='utf-8',
                               skiprows=1,
                               seq=';'
                               )

これで概ねよくなるが, データに意味のない空白があるので, それを取り除く.

dat = pd.read_csv('data.csv',
                                encoding='utf-8',
                                skiprows=1,
                                seq=';',
                                skipinitialspace=True)

これでおめあてのデータにすることができた.

ファイル入出力のあれこれ(バイナリ編)

昨日はcsvやら, エクセルデータの読み書きを見てきた. 今日はバイナリのデータでそれらを見る.
あとpandasも今日中に見ていく.

pickle

Pythonのオブジェクトをバイナリでそのまま保存/読み込みをする時に利用することができる.

import pickle

my_data = [1, 2, 3]

#ファイルに書き込み
with open('pickle1.pickle', 'wb') as f:
    pickle.dump(my_data, f)

#ファイルから読み込み
with open('pickle1.pickle', 'r') as f:
    pickle.load(f)

複数変数のpickle化は, 以下のように連続して書けばいい

import pickle
import numpy as np

a = np.float(2.3)
b = np.array([[1.1, 2.2, 3.3], [4.4, 5.5, 6.6]])
c = {'yokohama':1, 'tokyo':2, 'nagoya':3}

with open('pickle1.pickle', 'wb') as f:
	pickle.dump(a, f)
	pickle.dump(b, f)
	pickle.dump(c, f)

これだと次の問題が生まれる.
(1)順番にloadしなくては使えなくなる. いくつdumpされているのかがわからない場合もあり, try文で例外を見つける必要がある

(2)変数の名前が損なわれる. もう一回自分で付け直さなければならない

そこで, 辞書型でデータを活用するのが良いのだそう
それなら,(1)の問題も消え, execで実行していくことで,キーを変数にすることができるので(2)の問題も消える

 import pickle
import numpy as np

def pickle_vars(fname, mode='wb', **vars):
	# **varsは可変長のキーワード引数
	dic = {}
	for key in vars.keys():
		exec('dic[key]=vars.get(key)')

	with open(fname, mode) as f:
		pickle.dump(dic, f)

	return dic


if __name__ == '__main__':
	a = np.float(2.3)
	b = np.array([[1.1, 2.2, 3.3], [4.4, 5.5, 6.6]])
	c = {'yokohama':1, 'tokyo':2, 'nagoya':3}

	saved_dat = pickle_vars('pickle1.pickle', a=a, b=b, c=c)

	with open('pickle1.pickle', 'rb') as f:
		dat = pickle.load(f)
		for key in dat.keys():
			exec(key+'=dat.get(key)')

npy, npz形式

npy/npzはnumpyのデータを保存するためのもの.
npyはひとつのnumpyオブジェクトを保存する時に使用して, npzは複数のnumpyオブジェクトを保存する時に利用する. 以下に実際のコードをみていく

import numpy as np

a = np.array([1, 2, 3])
np.save('foo', a)

#ひとつのnumpyオブジェクトの場合, 自動的にnpyに変換される
a = np.load('foo.npy')

#npzは複数のnumpyオブジェクトの時に利用
b = np.array([1, 2], [3, 4])
np.savez('foo.npz', a=a, b2=b)

with np.load('foo.npz') as data:
   a2 = data['a']
   b2 = data['b2']

HDF5形式

データを階層構造にして保存することができる形式
実際にコードを見たほうが早い

import h5py
import numpy as np

t = np.arange(0, 5, 0.1)
y = np.sin(2*np.pi*0.3*t)
dist = [2, 5, 1, 3, 8, 9, 12]

with h5py.File('data1.h5', 'w') as f:
    f.create_group('wave')
    f.create_dataset('wave/t', data=t)
    f.create_dataset('wave/y', data=y)
    f.create_dataset('dist', data=dist)

#データの読み出し
with h5py.File('data1.h5', 'r') as f:
    t = np.array(f['wave/t'])
    y = np.array(f['wave/y'])
    dist = np.array(f['dist'])

ファイルの入出力のあれこれ(上)

Pythonでのファイルの入出力のあれこれのまとめ.
numpyの保存とかその辺りがメイン.

with文

基本的にopen単体で利用することはせず, with文を利用することが大半

with open('path', 'r', encoding='utf-8') as f:
    whole_file = f.read()
    print(f)

read()はファイルのすべてを取り出す. readline()は一行ずつなど. この時, 文字列に全て返還されることに注意する.
数字として扱いたい時はキャストを利用すること.

CSV

ここからは, 各主要なファイルでどのように読み込み, 書き込みをするのかを見ていく.
with文の場合, csvは読み込むことはできるが, 文字列としてインポートされるのであった.
標準モジュールのcsvを利用する場合を見ていこう.

with open('path', 'r', encoding='utf-8') as f:
    whole_file = csv.reader(f)
    print(f)

こちらも文字列として読み込まれるので, 数値を扱うcsvファイルの時はあまり向かない.
numpyにあるloadtxtを利用することもできる.

import numpy as np
data = np.array([1, 2, 3], dtype=np.int32)
np.savetxt('saved.csv', data, fmt='%d', header='time,vel,alt', comments='')

#numpy行列が一行の時, 列で保存されてしまう点に注意
#読み込みは以下(読み込む時はあまり関係ないようだ)

data = np.loadtxt('saved.csv', delimiter=',', skiprows=1, dtype=float)

# array([ 1.,  2.,  3.])

Excel

Excelファイルには拡張子がいくつかあり, それに応じて使うライブラリも異なる

(1)xls -> xlrd, xlwt
(2)ooxml -> openpyxl

これらを使い分ける.

xls

# xlsを使用する
# xlwt .. 書き込み xlrd .. 読み込み

wb = xlwt.Workbook()

ws = wb.add_sheet('シート1')

#書き込み
ws.write(0, 0, 'UpperLeft')
ws.write(1, 0, 1)
ws.write(1, 1, 2)
ws.write(1, 2, xlwt.Formula('A3+B3'))
wb.save('xlwt.xls')

#読み出す
wb = xlrd.open_workbook('xlwt.xls')
st = wb.sheet_by_name('シート1')
print(st.cell(0, 0).value)

openpyxlを利用する時

from openpyxl import load_workbook
import numpy as np

wb = load_workbook(filename='sample.xlsx', read_only=True, data_only=True, use_iterators=True)
ws = wb['温度変化']

Nrows = 11
time_vec = np.zeros(Nrows)
temp_vec = np.zeros(Nrows)

for i, row in enumerate(ws.iter_rows(row_offset=1)):
    time_vec[i] = row[0].value
    temp_vec[i] = row[1].value

明日はpickle, npyなどのバイナリデータや, pandasなどを見ていく.