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

tak0kadaの何でもノート

発声練習、生存確認用。

医学関連は 医学ノート

numpy.meanの実装が分からん

ThinkStatsの著者はテキスト中に現れる関数をpythonスクリプトで配布している。ところが実際にはこれらの関数の大半はnumpy,scipyで実装されている。実際どのようにして実装されているか調べたところメインの計算過程がCで実装されているらしいことが分かった。

numpy.meanを調べてみる。 scipyのレファレンスにmeanのドキュメントがあるので読んでみる。

f:id:kuyata:20140418164647j:plain

見慣れた感じのドキュメントである。

そこからソースコードに移動できる。github該当ページへ移動してmean()の返り値を見たところ、

return _methods._mean(a, axis=axis, dtype=dtype,
                            out=out, keepdims=keepdims)

となっているので12行目を見ると、

from . import _methods

さらに_method.pyに移動して_mean()を見る。

def _mean(a, axis=None, dtype=None, out=None, keepdims=False):
    arr = asanyarray(a)

    rcount = _count_reduce_items(arr, axis)
    # Make this warning show up first
    if rcount == 0:
        warnings.warn("Mean of empty slice.", RuntimeWarning)


    # Cast bool, unsigned int, and int to float64 by default
    if dtype is None and issubclass(arr.dtype.type, (nt.integer, nt.bool_)):
        dtype = mu.dtype('f8')

    ret = um.add.reduce(arr, axis=axis, dtype=dtype, out=out, keepdims=keepdims)
    if isinstance(ret, mu.ndarray):
        ret = um.true_divide(
                ret, rcount, out=ret, casting='unsafe', subok=False)
    elif hasattr(ret, 'dtype'):
        ret = ret.dtype.type(ret / rcount)
    else:
        ret = ret / rcount

    return ret

問題はret = um.add.reduce(arr, axis=axis, dtype=dtype, out=out, keepdims=keepdims)らしい。

11行目を見ると、

from numpy.core import umath as um

しかし、numpy.coreにはumathがない!/srcの中にはumathがあった。その中にはaddなるものは見当たらなく、.cファイルなどばかり。Cはまともに勉強していないのもはやここまでであるorz。とりあえず中身がCで実装されていることは分かった。その他の収穫は絶対インポートの使い方であった。setup.pyの書き方が分かったらもう少し何か分かるかもしれない。