DISTRICT 37

なにか

DB2のautocommit設定

DB2は自動コミットがデフォルトでONになっているので、うっかり更新してしまって泣くこともしばしば。ということで自動コミット(auto-commit)の設定方法。

auto-commitのデフォルト設定

DDLでもDMLでもCLI実行時にauto-commmit関連の設定を変えることで対応ができる。 IBM Knowledge CenterによるとCLI実行時に、下記の通りにオプションを読み込んで設定するとの事。

  1. デフォルト・オプションを設定します。
  2. DB2OPTIONS を読み取って、デフォルトを一時変更します。
  3. コマンド行を読み取って、DB2OPTIONS を一時変更します。
  4. UPDATE COMMAND OPTIONS からの入力を、最終的な対話式一時変更として受け入れます。

デフォルト設定は以下のコマンドで確認できる

db2 ? options

確認するのにヘルプコマンドを使うのが気持ち悪いが、これで出てくる値がデフォルト。自動コミットはONとなっている。

オプション  説明                                       現在の設定
------  ----------------------------------------  ---------------
(略)
  -c    自動コミット                              ON
(略)

このデフォルト設定は頑張ったけどどうも変えられないので、2か3で対応したらいい。4はよくわからんので割愛。

DB2OPTIONSの設定

DB2環境変数としてDB2OPTIONSを設定することでデフォルトを上書きできる。なので、この対応でとりあえずは完了かと。

まずはDB2OPTIONSの確認。

db2 list command options

DB2OPTIONSの確認とか言いながらcommand optionsと打つのがまた気持ち悪い。

オプション  説明                                       現在の設定
------  ----------------------------------------  ---------------
(略)
  -c    自動コミット                              ON
(略)

変更前ならデフォルト設定と同じ値が設定されているはず。次のコマンドでこの値を更新する。

db2set DB2OPTIONS=+c

これで自動コミットをOFFに設定できる。DB2OPTIONS=に続いた「-c」でONにして「+c」でOFFにするというまたまた直観的ではない気持ち悪い設定。これでDB2OPTOINSを確認すると確かに自動コミットがOFFになっているのがわかる。

オプション  説明                                       現在の設定
------  ----------------------------------------  ---------------
(略)
  -c    自動コミット                              OFF
(略)

コマンド発行時に設定

例えばUPDATEのSQLとかを書く時に設定ができる。ここでDB2OPTIONで設定した値をさらに上書きできる。

db2 +c update your_table set cl1 = 'foo'

updateの前に「+c」を付けることで自動コミットをOFFにできる。DB2OPTIONSと同様に「-c」で自動コミットをONにすることも可能。実質ここの設定が王様になるので本来はSQLを打つ時にこれを設定すクセをつけるべきなんだろうと思う。まぁこれはSQLにおけるDB2の方言なので、他のRDBMSに応用できないから別にいいですね。

auto-commitに限らず他のオプションも同様の対応でいいかと。

木星の惑星エウロパから水蒸気のようなもの

www.nasa.gov

プロキシマbは水の存在の可能性という事だったが、エウロパにおいて水蒸気のようなものが確認されたとNASAが発表した。日本時間の9/24にNASAが「9/26に驚くべき発表するからな」と言ったニュースがこれ。NASAはたびたびこんな感じでもったいぶって発表する。前回は「火星に水があったかもしれん!」といったそれだけ?って感じのふんわりしたニュースだった気がする。今回のエウロパの件も前々から指摘されていたので、驚いたといえば驚いたし、驚かなかったといえば驚かなかった。

折しも東京で「豊洲市場に地下水ガー」と話題になっている際に「エウロパに地下水ガー」とニュースになり、同じ地下水でも歓喜する人と目くじら立てる人に分かれているようだ。

プロキシマ・ケンタウリbという星

wired.jp

Civilizationファンならアルファ・ケンタウリという名前を聞いたことがあると思う。ゲーム内で技術を高めて宇宙船を作り、アルファ・ケンタウリに旅立てれば科学勝利となる。アルファ・ケンタウリとはケンタウルス座α星という俺たちの太陽系からもっとも近い恒星だ。そのアルファ・ケンタウリは3連星となっており、それぞれアルファ、ベータ、プロキシマと名付けられている。この3連星でも最も近い恒星はプロキシマであり、プロキシマという名前自体も「最も近い」という意味になっている。太陽系には水星から始まり、金星、地球、火星、木星、、、と惑星が連なっている。この度プロキシマ・ケンタウリという恒星系に惑星が発見され、その名がプロキシマ・ケンタウリbである。

近い

そう、地球から近いのである。地球を含む太陽系以外の惑星を太陽系外惑星と分類され、全天中でいくつも発見されているが、どれもこれも当然のように遠い。1000光年とか1万光年といった、気が遠くなる距離であった。ところがこのプロキシマbは4.2光年と比較的現実的な距離で発見された。サンプルリターンでおなじみの小惑星イトカワから帰還した「はやぶさ」の飛行距離が60億キロほどなので、0.0006光年といったところ。

太陽系でも距離感はこんな感じ。4光年が近いような遠いような

天体 距離
1.3光秒
太陽 8光分
火星 13光分
金星 8光分
木星 40光分
土星 80光分

引用:主な天体までの距離と大きさ

生命の存在

決め手は水だ。プロキシマbには水が存在する可能性が指摘されている。恒星に近いほど熱で水は蒸発してしまい、恒星から遠ざかるほど水は凍ってしまう。実はプロキシマbはプロキシマ・ケンタウリにほど近い場所にあるので、水が蒸発してしまうのではと懸念されたが、どうやらプロキシマ・ケンタウリはそのほかのアルファやベータに比べて小さく、熱もそれほど発しないと推測されている。系の中で水が液体を保てる距離をハビタブルゾーン(正確には生命居住可能域)と呼ばれているが、プロキシマbはそこにあり、水が存在するかもと推測されている。水さえあれば生命の存在が期待できる。それがヒトのように知的生命であればコンタクトだってとれるようになる。

火星でも木星の衛星エウロパでもそうだけど、宇宙探査ではとにかく水を探したがる。水に頼らない生命というのは検討に値しないのだろうか。

さぁ行こう

ブレークスルー・スターショット - Wikipedia

(比較的)現実的な距離ということで、無人探査機を送り込む計画が立てられている。その名もブレークスルー・スターショットとかっこいい。ロシアの富豪とホーキング博士によって発表されたプロジェクトだ。帆にレーザーを照射して光速の20%ほどの速度でプロキシマbにたどり着き、調査をするという計画だ。残念ながら理論のみが先行しており、ミッションに必要な技術がほとんど存在していないというのがとても悲しい。ベテルギウス超新星爆発に並んで、僕が生きている間に何とかなっていればうれしいことの一つだ。

果たして科学勝利まであと何ターンなのだろうか

matplotlibが描画されない

普段コードを書くときはjupyterを使っていて、matplotlibのプロットがブラウザ内に行われるの為この問題には気付かなかった。改めてpythonのコードを書いてみて描画関連でエラーが出ていることに気が付いた。

環境

  • Ubuntu16.02
  • python 3.5.1 (pyenv)
  • matplotlib 1.5.2

何が起こったか

最初はmatplotlibで描画するコードであるplt.show()としてもウンともスンとも言わなかった。で探しているうちにmatplotlibのbackendにTkを指定しないと描画が行われないとの情報があった。それを指定したのちにplt.show()を実行したら「ImportError: Nomodule named '_tkinter'」と出た。jupyter上では問題無く動くコードなのに、pythonのコードとして実行するとエラーを吐いて描画が行われなかった。

---> 35 import _tkinter # If this fails your Python may not be configured for Tk
     36 TclError = _tkinter.TclError
     37 from tkinter.constants import *

ImportError: No module named '_tkinter'

エラーメッセージには「キミの使っているpythonにTk関連のセットアップが済んでいないよ」と表示されている

解決方法

TK関連のライブラリを入れて、pythonの入れ直しをしたら直る。入れててよかったpyenv。

準備としてpip関連のパッケージ情報を吐きだしておく。何を入れていたかなんて当然覚えちゃいない。

pip freeze > pip.txt

まずはpythonのアンインストール。pyenvでどのバージョンのpythonを使っているか確認してからでもいいかも。

pyenv versions
pyenv uninstall 3.5.1

続いてTK関連のライブラリをインストール

sudo apt install python-tk tk-dev

そのあとでpythonを再インストール

pyenv install 3.5.1

終わったらpipのパッケージを一括インストール

pip install -r pip.txt

注意点としてscikit-learnが入っていた場合は先にScipyを入れないとエラーを起こして止まる。freezeで出力したファイルはアルファベット順にソートされていてscikit-learn、Scipyの順に記述されている。一括インストールではその順にインストールが行われるのでファイル自体の順番を編集するとか、指摘通りにScipyを先に入れちゃうとかやっておくといい。

作業としてはこれでおしまい。

確認

matplotlibrcというファイルにbackendの指定をする必要がある。場所はmatplotlib自身が教えてくれる

import matplotlib
print(matplotlib.matplotlib_fname())

# こんな感じで標準出力に出る
# '/home/yourname/.pyenv/versions/3.5.1/lib/python3.5/site-packages/matplotlib/mpl-data/matplotlibrc'

該当ファイルをエディタで開いて「backend」を「tkagg」に更新する

backend   :tkagg

このbackendが適切なものに指定されていないとmatplotlibはちゃんと描画されない。pythonのコード中に書いて指定することもできるが、そもそもライブラリが入っていなくて使えない場合は指定してもだめ。

以下のサンプルはjupyterだけど、pythonのコードを書いて無事にサインカーブが描画されたら確認完了。

原因

上記のエラーメッセージの通りpythonインストール時にTK関連のライブラリが無いとmatplotlibの描画時にTKが使われないとの事。後付けでできないかいろいろ探し回ったけど、再インストールが手っ取り早かった。

参考

qiita.com

Pandasの基本操作

Pandasの操作シリーズ 第二弾

前回 dragstar.hatenablog.com

データの基本操作

所謂基本統計量がとれる

www.mm-lab.jp

  • 最大値の取得
df.max()
  • 最小値の取得
df.min()
  • 平均値の取得
df.mean()
  • 中央値の取得
df.median()
  • 分散の取得
df.var()
df.std()
  • 合計値の取得
df.sum()
  • 尖度
df.kurt()
  • 歪度
df.skew()
  • 基本統計量
df.describe()

行の追加

行を追加する場合は列を合わせておくこと

df = df.append(new_df)

列の追加

列を追加する場合はデータ量を合わせておくこと

df['new_col'] = new_df

値の取得

  • 行単位で取得する。

戻り値はSeries

df.ix[0]

複数行を取得する。この場合はDataFrameが戻り値となる

df.ix[[0,2]]
  • 列単位で取得する。

戻り値はSeries

df['column_name']

複数列を取得。こちらもDataFrameとなる

df[['column_name','other_column']]

条件を満たすデータを選択

df[df['column_name'] > 30]

データの個数を数える

  • 列に出てきた値の個数を数える。

度数分布とかに便利

df['column'].value_counts()

単純に数を数える場合

df['column'].count()

df.count() #すべての列を対象にする
len(df) #単純にこれでもいい

欠損値の扱い

  • 欠損値を含むデータを削除
df.dropna()
  • NaNを埋める

指定した文字で埋める

df.fillna(0)

Pandasでcsvを操作

Pandasの操作シリーズ

CSVファイルからPandasを作る

こういうCSVデータがあったとする。

no,Sepal.Length,Sepal.Width,Petal.Length,Petal.Width,Species
1,5.1 ,3.5 ,1.4 ,0.2 ,setosa
2,4.9 ,3.0 ,1.4 ,0.2 ,setosa
3,4.7 ,3.2 ,1.3 ,0.2 ,setosa

まずは基本系

import pandas as pd #以下省略
df = pd.read_csv("hoge.csv")
print(df)

結果としてこうなる。デフォルトで一行目がタイトルとなり、0から始まるインデックス列が自動的に付与される。

no Sepal.Length Sepal.Width Petal.Length Petal.Width Species
0 1 5.1 3.5 1.4 0.2 setosa
1 2 4.9 3.0 1.4 0.2 setosa
2 3 4.7 3.2 1.3 0.2 setosa

インデックスを指定したい場合はindex_colを指定

import pandas as pd #以下省略
df = pd.read_csv("hoge.csv", index_col="no")
print(df)

指定した列がインデックス列となる

no Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa

タイトルがなく、一行目からデータがある場合はheaderパラメータを指定する。

df = pd.read_csv("hoge.csv", header=None)
print(df)

タイトルが自動的にふられて読み込まれる。

no 1 2 3 4 5
0 1 5.1 3.5 1.4 0.2 setosa
1 2 4.9 3.0 1.4 0.2 setosa
2 3 4.7 3.2 1.3 0.2 setosa

そういったデータにヘッダーを付けて読み込みたい場合はnamesパラメータを指定する。

df = pd.read_csv("hoge.csv", names=('a','b','c','d','e'))
print(df)

指定したヘッダーで読み込まれる

no a b c d e
0 1 5.1 3.5 1.4 0.2 setosa
1 2 4.9 3.0 1.4 0.2 setosa
2 3 4.7 3.2 1.3 0.2 setosa

カンマ区切りではなく、タブ区切りの場合にはdelimiterを指定する

df = pd.read_csv("hoge.csv", delimiter='\t')

delimiterを指定することで、タブだけでなく他の区切り形式でも読み込むことができる。

PandasからCSVを作る

まずは基本系

import pandas as pd #以下省略
df.to_csv("hoge/hoge/iris.csv")

デフォルトではインデックスがつく

,no,Sepal.Length,Sepal.Width,Petal.Length,Petal.Width,Species
0,1,5.1 ,3.5 ,1.4 ,0.2 ,setosa
1,2,4.9 ,3.0 ,1.4 ,0.2 ,setosa
2,3,4.7 ,3.2 ,1.3 ,0.2 ,setosa

インデックスを外したい場合はindexをFalseに指定する

df.to_csv("hoge/hoge/iris.csv", index=False)

デリミタをタブにしたい場合はsepを指定する

df.to_csv("hoge/hoge/iris.csv", sep="\t")

他の区切り文字でもいける。

また、データをquoteで囲む場合はquotingを指定する

import csv
df.to_csv("hoge/hoge/iris.csv", quoting=csv.QUOTE_ALL)

Rのパッケージを一括アップデート

pythonに続きRでもそれをやる

dragstar.hatenablog.com

パッケージを一括アップデート

update.packages()

このコマンドを打ったのちにCRANと既存パッケージのバージョン比較が自動的に行なわれる。だが、パッケージごとに更新してもいいか「Update (y/N/c)?」と確認してくるので、インストールしているパッケージが多ければ多いほど、しかもそれがアップデート対象だと少々厄介。いうまでもないが「y」がyes、「N」がNo、「c」がcancelだ。

Rsutdioだと簡単

Rstudioだとこれが格段に簡単になってくる。左下(デフォルトだと)のPackegesタブを選択して「Update」ボタンを押すと同様にCRANとの比較をして更新状況を確認する。この中から更新対象を選択して「Install Updates」を押したら完了。「Select All」を押したらすべて選択状態になるという地味に便利な補助機能付き。

f:id:dragstarclassic:20160909112313j:plain

パッケージってそれほど劇的に内容が変わるわけでもないので、バグでも見つけない限りインストール済みのパッケージは結構放っておきがち。新しいものにしておくに越したことはないが、引数が強制的に増減したり、さらには関数自体無くなったりとやっかいな変更もあったりするので、パッケージ管理は一概に最新にしておくのがいいってわけではないのかと。ReleaseNoteとか見て判断するのもいいかもしれない。