トップページに戻る

Numpyの基礎(8)ファイル入出力

In [1]:
import numpy as np
import matplotlib.pyplot as plt

# jupyter notebookに画像を表示
%matplotlib inline

ndarrayのファイル入出力

Numpyで扱えるファイル入出力は

  • 一般的なバイナリ
  • テキスト
  • Numpy独自のバイナリ

の3つに分けられます。

StringIOはファイル入力の代わりに文字列を渡すことができるインターフェイスです。
あんまり気にしないでください。

In [2]:
from io import StringIO

ファイル入力

テキストファイルから読み取る

Numpyでテキストファイル入力を取り扱う関数として、loadtxtや、より高機能なgenfromtxtがあります。
個人的にはこれらを使う機会はほとんどなく、pandasというデータ分析用ライブラリを使ってテキストファイル入力を取り扱っています。
Numpyのページで紹介するのも気が引けますが、pandasで読み取ったあと、ndarrayを取り出せば結局同じことなので、この項ではpandasのファイル入力を紹介します(多分こちらのほうが簡単)。

In [3]:
# Anacondaで入れた場合はすでに使用可能。
# エラーが出た人は、pipでインストールしてください。
import pandas as pd

CSVファイルから読み取る

CSVファイルとは「,」で区切られたファイルのことです。
一般的には、float, int, 文字列が混在しています。

In [4]:
file = """
I1,I2,F1,I3,S1
1,1,1.9029e+2,3,アツアツ
3,2,8.24608e-1,9,萎え萎え
"""
df = pd.read_csv(StringIO(file), delimiter=',')
df
Out[4]:
I1 I2 F1 I3 S1
0 1 1 190.290000 3 アツアツ
1 3 2 0.824608 9 萎え萎え
In [5]:
# 実際は以下のようにパスを指定する。
# df = pd.read_csv('data.csv', delimiter=',')

上で得られたオブジェクトは、pandas.DataFrameというものです。
自動的に型を読み取り、適切なdtypeにしてくれます。

In [6]:
df.dtypes
Out[6]:
I1      int64
I2      int64
F1    float64
I3      int64
S1     object
dtype: object

valuesでndarrayを取得できます。
これはコピーではなく、単なる参照です(pandas.DataFrameは内部でndarrayを保持しています!)。

In [7]:
df['I1'].values
Out[7]:
array([1, 3], dtype=int64)
In [8]:
# 確かにndarray
type(df['I1'].values)
Out[8]:
numpy.ndarray
In [9]:
# headerがないバージョン
file = """
1,1,1.9029e+2,3,アツアツ
3,2,8.24608e-1,9,萎え萎え
"""
df = pd.read_csv(StringIO(file), header=None, delimiter=',')
df
Out[9]:
0 1 2 3 4
0 1 1 190.290000 3 アツアツ
1 3 2 0.824608 9 萎え萎え

固定長幅テキストファイルから読み取る

区切り文字ではなく、「幅」で列を区切るタイプのテキストファイルです。
widthsに列ごとの文字数を指定すると読み取れます。

In [10]:
s = """         VALUE1            VALUE2         ID
+1.87429510e+00   -4.44966444e-02   00030109
-1.83643507e+00   -1.87712943e+00   04005971
+5.11761193e-01   -5.57850439e-01   00000750
"""
df = pd.read_fwf(StringIO(s), widths=(16, 19, 11))
df
Out[10]:
VALUE1 VALUE2 ID
0 1.874295 -0.044497 30109
1 -1.836435 -1.877129 4005971
2 0.511761 -0.557850 750
In [11]:
# ndarrayが取得できるように
df[['VALUE1', 'VALUE2']].values
Out[11]:
array([[ 1.8742951 , -0.04449664],
       [-1.83643507, -1.87712943],
       [ 0.51176119, -0.55785044]])

バイナリ入力

fromfileとかあるみたいです。

ファイル出力

Numpyでファイル出力する場合、

  • 「.npyまたは.npz」形式でのバイナリ保存
  • テキストでの保存
  • 一般的なバイナリ保存

の3つが基本となります。本稿では上の2つを説明します。

npyとnpz形式でのバイナリ保存

これらはNumpy独自のバイナリ形式です。
np.save関数では、ndarrayを npy という拡張子を付けて保存します。
この形式だと、配列のshapeやdtypeなどの情報も保存するので、np.loadで情報を保ったまま読み込むことが出来ます。
複数のndarrayを保存するときは np.savez 関数を用いて、npz という拡張子で保存します。
npz形式の場合のロードも np.load 関数を使います(拡張子で判断される)。
まずはnpyの保存をみてみましょう。

In [12]:
arr = np.linspace(3, 4, 100).reshape(10, 10, 1)

# arrをnpy形式で保存
np.save("test_arr.npy", arr)

# npyをロード
arr_new = np.load("test_arr.npy")

# 全ての要素が等しいならTrue
np.all(arr == arr_new)
Out[12]:
True

npzでは、キーワード引数を渡すと、その名前で保存されます。

In [13]:
my_x = np.linspace(0,  1, 10) ** 3
my_y = np.arange(0, 10)

# キーワード引数でndarrayをsavezに渡す
np.savez("test_arrs.npz", x = my_x, y = my_y)

arrs = np.load("test_arrs.npz")

arrs["x"]
Out[13]:
array([0.        , 0.00137174, 0.01097394, 0.03703704, 0.0877915 ,
       0.17146776, 0.2962963 , 0.47050754, 0.70233196, 1.        ])

テキストでの保存

ndarrayをテキスト形式で保存する関数はnp.savetxtです。

In [14]:
# 2次元配列
x = np.linspace(0, 1, 10).reshape(5,2)

# xをテキスト形式で保存
np.savetxt("my_np.txt", x)
In [15]:
# 保存したテキストファイルを表示
!cat my_np.txt
0.000000000000000000e+00 1.111111111111111049e-01
2.222222222222222099e-01 3.333333333333333148e-01
4.444444444444444198e-01 5.555555555555555802e-01
6.666666666666666297e-01 7.777777777777776791e-01
8.888888888888888395e-01 1.000000000000000000e+00

誤字やおかしい点などがあったら @zawawahoge (Twitter) にお気軽にご連絡ください。

トップページに戻る