Posted at

numpy.savetxtで標準出力

More than 1 year has passed since last update.

何かしらの処理の結果得られたnumpy配列を標準出力に流したい、という時の方法。

Python2系と3系で微妙に違ったので両方書きます。


Python2系

numpy配列をファイルに保存する関数としてnumpy.savetxt()がありますが、

引数の保存先にsys.stdoutを指定することでnumpy配列を標準出力に流すことができます。


  • サンプルコード


save_stdout_2.py

import sys

import numpy as np

X = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
np.savetxt(sys.stdout, X)



  • 実行

$ python save_stdout_2.py

1.000000000000000000e+00 2.000000000000000000e+00 3.000000000000000000e+00
4.000000000000000000e+00 5.000000000000000000e+00 6.000000000000000000e+00


Python3系

基本的には2系と同じなのですが、そのままsave_stdout_2.pyを実行すると次のようなエラーが出ます。

$ python save_stdout_2.py

...
TypeError: Mismatch between array dtype ('float64') and format specifier ('%.18e %.18e %.18e')

以下によると、どうやらPython3系においてnumpy.savetxt()はバイナリモードで書き込むことを前提としているらしいです。

https://stackoverflow.com/questions/35372829/numpy-savetxt-resulting-a-formatting-mismatch-error-in-python-3-5


savetxt opens the file in wb mode, and thus writes everything as bytes.


そこで出力先をsys.stdout.bufferに変更します。これはバイナリデータの読み書きを行うオブジェクトです。


  • サンプルコード


save_stdout_3.py

import sys

import numpy as np

X = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
np.savetxt(sys.stdout.buffer, X)



  • 実行

$ python save_stdout_3.py

1.000000000000000000e+00 2.000000000000000000e+00 3.000000000000000000e+00
4.000000000000000000e+00 5.000000000000000000e+00 6.000000000000000000e+00

Python2系と同じ出力を得ることができました。


おまけ-標準入力

np.loadtxt()の読み込み先をsys.stdinにすることで標準入力の文字列をnumpy配列に入れることができます。


  • サンプルコード


load_stdin.py

import sys

import numpy as np

X = np.loadtxt(sys.stdin)


これを使えばシェルのフィルタコマンドでは困難な処理もPythonで書くことができます。