[解決!Python]CSVファイルに書き込みを行うには(NumPy編):解決!Python
NumPyが提供するsavetxt関数関数を使って、CSVファイルなどにデータを書き込む方法を紹介する。
import numpy as np
from pathlib import Path
x = np.random.randn(2, 3) # 以下の値は一例
print(x)
#[[-2.45567984 1.33310634 0.59013369]
# [ 0.25731195 0.78458477 -0.64572527]]
# 基本的な使い方
np.savetxt('test.csv', x)
print(Path('test.csv').read_text())
#-2.455679835942072398e+00 1.333106339746787494e+00 5.901336922847821853e-01
#2.573119457585911207e-01 7.845847696453233100e-01 -6.457252711716952032e-01
# 区切り文字を変更する
np.savetxt('test.csv', x, delimiter=',') # 区切り文字をカンマ「,」に
print(Path('test.csv').read_text())
#-2.455679835942072398e+00,1.333106339746787494e+00,5.901336922847821853e-01
#2.573119457585911207e-01,7.845847696453233100e-01,-6.457252711716952032e-01
# 書き出すフォーマットの指定
# 指数表記
np.savetxt('test.csv', x, fmt='%.8e') # 小数点以下の精度を8桁に
print(Path('test.csv').read_text())
#-2.45567984e+00 1.33310634e+00 5.90133692e-01
#2.57311946e-01 7.84584770e-01 -6.45725271e-01
np.savetxt('test.csv', x, fmt='%18.8e') # 最小の出力幅を指定
print(Path('test.csv').read_text())
# -2.45567984e+00 1.33310634e+00 5.90133692e-01
# 2.57311946e-01 7.84584770e-01 -6.45725271e-01
# 浮動小数点数値(指数表記をしない)
np.savetxt('test.csv', x, fmt='%12.8f') # 精度の後に「f」を指定
print(Path('test.csv').read_text())
# -2.45567984 1.33310634 0.59013369
# 0.25731195 0.78458477 -0.64572527
# 左寄せ
np.savetxt('test.csv', x, fmt='%-18.8e') # 「-」で左寄せを指定
print(Path('test.csv').read_text())
#-2.45567984e+00 1.33310634e+00 5.90133692e-01
#2.57311946e-01 7.84584770e-01 -6.45725271e-01
# 符号を常に付加
np.savetxt('test.csv', x, fmt='%+18.8e') # 「+」で符号を常に付加
print(Path('test.csv').read_text())
# -2.45567984e+00 +1.33310634e+00 +5.90133692e-01
# +2.57311946e-01 +7.84584770e-01 -6.45725271e-01
# 0埋め
np.savetxt('test.csv', x, fmt='%018.8e') # 「0」で0埋めを指定
print(Path('test.csv').read_text())
#-0002.45567984e+00 00001.33310634e+00 00005.90133692e-01
#00002.57311946e-01 00007.84584770e-01 -0006.45725271e-01
# 整数値
nums = np.array([[111, 222, 333],
[444, 555, 666]])
np.savetxt('test.csv', nums, fmt='%d')
print(Path('test.csv').read_text())
#111 222 333
#444 555 666
np.savetxt('test.csv', nums, fmt='%.5d') # 0埋め
print(Path('test.csv').read_text())
#00111 00222 00333
#00444 00555 00666
np.savetxt('test.csv', nums, fmt='%6d') # 出力される最小の文字数を指定
print(Path('test.csv').read_text())
# 111 222 333
# 444 555 666
np.savetxt('test.csv', nums, fmt='%6.4d') # 数字の最小文字数を指定
print(Path('test.csv').read_text())
# 0111 0222 0333
# 0444 0555 0666
# 改行文字を変更する
np.savetxt('test.csv', x, newline='\n\n')
print(Path('test.csv').read_text())
#-2.455679835942072398e+00 1.333106339746787494e+00 5.901336922847821853e-01
#
#2.573119457585911207e-01 7.845847696453233100e-01 -6.457252711716952032e-01
#
# ヘッダーを付加する
np.savetxt('test.csv', x, header='col1 col2 col3')
print(Path('test.csv').read_text())
## col1 col2 col3
#-2.455679835942072398e+00 1.333106339746787494e+00 5.901336922847821853e-01
#2.573119457585911207e-01 7.845847696453233100e-01 -6.457252711716952032e-01
# フッターを付加する
np.savetxt('test.csv', x, footer='generated: 2021/08/27')
print(Path('test.csv').read_text())
#-2.455679835942072398e+00 1.333106339746787494e+00 5.901336922847821853e-01
#2.573119457585911207e-01 7.845847696453233100e-01 -6.457252711716952032e-01
## generated: 2021/08/27
基本的な使い方
NumPyが提供するnumpy.savetxt関数(以下、savetxt関数)を使うと、NumPyの配列、リストなどの値を、特定の文字で区切って、CSVファイルなどに出力できる。ただし、出力可能なのは1次元または2次元の配列やリスト(array_likeオブジェクト)に限る。
savetxt関数の構文を以下に示す。
numpy.savetxt(fname, x, fmt='%.18e', delimiter=' ', newline='\n', header='',
footer='', comments='# ', encoding=None)
指定可能なパラメーターは次の通り。
- fname:書き込みを行うファイルの名前。必須
- x:書き込むデータ。必須
- fmt:xに格納されているデータを出力する際に使われる書式指定。省略可能。省略時は「%.18e」が指定されたものと見なされる(精度が18桁の指数表記)
- delimiter:区切り文字。省略可。省略時の区切り文字は空白文字となる
- newline:行末文字の指定。省略可。省略時は改行文字「'n'」が指定されたものと見なされる
- header:ファイルの先頭に付加されるヘッダー行の指定。省略可。省略時にはヘッダーは付加されない
- footer:ファイルの末尾に付加されるフッター行の指定。省略可。省略時にはフッターは付加されない
- comments:コメント行であることを示す文字列。この文字列に続けて、headerパラメーターとfooterパラメーターで指定された文字列が書き込まれる。省略可。省略時には「# 」が指定されたものとして見なされる
- encoding:ファイルのエンコーディング指定
最も基本的な使い方を以下に示す。
import numpy as np
from pathlib import Path
x = np.random.randn(2, 3)
print(x)
#[[-2.45567984 1.33310634 0.59013369]
# [ 0.25731195 0.78458477 -0.64572527]]
# 基本的な使い方
np.savetxt('test.csv', x)
print(Path('test.csv').read_text())
#-2.455679835942072398e+00 1.333106339746787494e+00 5.901336922847821853e-01
#2.573119457585911207e-01 7.845847696453233100e-01 -6.457252711716952032e-01
この例では、2行3列のNumPy配列(numpy.ndarray)を作成して(その値はランダムであるため、読者が本稿のコードを実行したときには、違う値の配列が得られる点には注意されたい)、それをsavetxt関数に渡しているだけだ。出力されたファイルの内容を見ると、小数点以下の精度が18桁の指数表記の値が空白文字で区切られて出力されていることが分かる。これはfmtパラメーターのデフォルト値が「#.18e」(小数点以下の精度が18桁の指数表記)に、delimiterのデフォルト値が「' '」(空白文字)となっているからだ。
なお、上記ではNumPy配列を扱っているが、例えばPythonのリストもこの関数を使って書き出せる。
mylist = x.tolist()
np.savetxt('test.csv', mylist)
print(Path('test.csv').read_text())
#7.731030073194588015e-01 -1.741182180141600311e+00 9.348418996663322711e-02
#4.149555709304568740e-01 -1.150815368506415970e+00 -7.909651117231002171e-02
区切り文字を変更する
区切り文字を変更するには、delimiterパラメーターに区切り文字を指定する。以下に例を示す。
np.savetxt('test.csv', x, delimiter=',') # 区切り文字をカンマ「,」に
print(Path('test.csv').read_text())
#-2.455679835942072398e+00,1.333106339746787494e+00,5.901336922847821853e-01
#2.573119457585911207e-01,7.845847696453233100e-01,-6.457252711716952032e-01
ここでは、「delimiter=','」としているので、出力ファイルの内容を見ると、各値がカンマで区切られている。
書き出すフォーマットの指定
fmtパラメーターには、各要素を出力時にどのように書式化するかを指定できる。その値は「%[flag][width][.precision]specifier」という形式で指定する。先頭の「%」とspecifierに指定する値以外は省略可能だ。
- flag:書式化された値を左寄せにするか、符号を常に付加するか、0埋めするかを指定
- width:各値が最小で何文字を使って書式化されるかを指定
- .precision:specifierに「d」または「i」を指定したときには(整数)数字を使って出力される最小の文字数を指定。specifierに「e」、「E」、「f」を指定したときには(実数)小数点以下の精度を指定、specifierに「s」を指定したときには(文字列)文字列の最大文字数を指定
- specifier:各値を整数として書式化するときには「d」または「i」を指定する。実数として書式化するときには「e」「E」(指数表記)、または「f」(小数表記)を指定する。文字列として書式化するときには「s」を指定する。specifierには他にも「g」「G」「o」「u」「x」「X」を指定できるが、本稿では取り上げない。詳細についてはNumPyのドキュメント「numpy.savetxt」を参照のこと
例えば、配列の要素を指数表記でCSVファイルに書き込むには次のようにする。
np.savetxt('test.csv', x, fmt='%.8e') # 小数点以下の精度を8桁に
print(Path('test.csv').read_text())
#-2.45567984e+00 1.33310634e+00 5.90133692e-01
#2.57311946e-01 7.84584770e-01 -6.45725271e-01
上の例では「%」の後には.precisionとして「.8」が、specifierとして「e」が記述されている(flagとwidthは省略)。このため、小数点以下8桁の指数表記の数値としてCSVファイルに書き込みが行われている。
Copyright© Digital Advantage Corp. All Rights Reserved.