Numpy Tips 2 : データ欠損のある配列に対して代数演算などを行いたい

データ欠損のある配列に対して代数演算などを行いたい場合 numpy.ma.MaskedArray を用いたフィルタリングが便利だ. 具体的にはarrayにnanとinfが入ったものを加法演算する場合を考える.


import numpy as np
from numpy import ma

a=np.array([np.inf,np.nan,1,2,3])

mask=np.isinf(a) + np.isnan(a)

masked_a=ma.masked_array(a , mask=mask)
print masked_a 
# > [-- -- 1.0 2.0 3.0]

print masked_a.sum()
#>6


c++const修飾子の代替物@numpy mcbiophys.hatenablog.com

Pythonでいい感じにヒストグラムを自動生成してくれる機能

結論からいうと、pythonの主要ライブラリ(numpy + matplotlib)ではまだ実現できない.

Histogram with Optimal Binwidth

numpy.histogram という機能がnumpyには存在する これとfrom matplotlib import pyplotなどを利用すると pythonで簡単にヒストグラムグラフを書くことができる. 具体的には pyplot.histという関数を使うのだが、この関数のデフォルトのbinの数が10に固定されており 放り込むデータ数に関係なくbin数10でプロットしようとしてくる. R言語ではbin数をいい感じに最適化してくれる機能があるそうだ *1. ヒストグラムってデータ解析の第一歩なので、なるべく手軽にやりたい。 そこでpythonにもR言語のようなoptimal なbin数を出す機能を追加しようという提案がなされた.

ENH: Automatic number of bins for np.histogram by nayyarv · Pull Request #6029 · numpy/numpy · GitHub

optimalなbin数をはじき出すためにはそれなりに複雑な計算を要するため、 追加するのはmatplotlibにではなくnumpyコミュニティの方で行うようだ。

ということで、この機能が追加されるまではpython + numpy + matplotlibではまだ、bin幅を自動最適化することはできないみたいだ

Edit :

New in version 1.11.0. If bins is a string from the list below, histogram will use the method chosen to calculate the optimal bin width and consequently the number of bins (see Notes for more detail on the estimators) from the data that falls within the requested range. While the bin width will be optimal for the actual data in the range, the number of bins will be computed to fill the entire range, including the empty portions. For visualisation, using the ‘auto’ option is suggested. Weighted data is not supported for automated bin size selection.

Ref: http://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html#numpy-histogram

mcbiophys.hatenablog.com

mcbiophys.hatenablog.com

*1:hist() 関数では、自動的に階級数を決める方法として、 スタージェス/nclass.Sturges,フリードマン-ディアコニス/nclass.scott ,スコット/nclass.FD などの流儀が存在するらしい.このリンク先が参考に成る→ヒストグラム作成の裏側: R 関数探訪 hist() 編 - ほくそ笑む

Numpy Tips 1 : イミュータブルなnumpy array

python にはc++constの役割を果たす機能はないが、

constの完全な代替にはならないものの、

numpyなら以下のようにndarray.flagsを設定することでimputable arrayを実現することができる。

a = np.arange(5)
a.flags.writeable = False #a.flags["WRITABLE"]=False is also ok 
a[0] = 1
#ValueError: assignment destination is read-only

また以下のメソッドが同等の効果をもつ

a.setflags(write=False)

ただしこれはあくまでnumpyの配列変更を禁止するだけで、numpy自体の型変換はできてしまう。 すなわち、以下の代入は許される

a=1
type(a)
#int

cf. Python におけるside effectがないプログラミング(いわゆる関数プログラミング) の良し悪しについては、 5. Functions — Beginning Python Programming for Aspiring Web Developers などを参照

Python例外処理Tips ① 配列要素に対する写像をうまく実装する

例外処理Tipsシリーズ第一弾は

例外処理をうまく利用して列要素に対する写像をうまく実装する方法について説明します

具体的にはいわゆるFortranでいうところのelemental function をpython で実現する際に例外処理をうまく使えるとい話です。

def elemental_function(A, B, function):
    try:
        return [elemental_function(a, b, function) for a, b in zip(A, B)]
    except TypeError as e:
        return function(A, B)

def Sum(A,B):
    return A+B


a=[1,[ 1 ,2]]
b=[2,[ 3  ,4 ]]

print elemental_function(a,b,Sum)

#>[3, [4, 6]]