ファイルから生データを文字列に読み取ってからnp.fromstring
、行列の上三角部分の 1 次元配列を取得するために使用できます。
with open('data.txt') as data_file:
data = data_file.read()
arr = np.fromstring(data, sep=' ')
または、一度にファイルの 1 行を読み取るようにジェネレーターを定義してnp.fromiter
から、このジェネレーターから 1 次元配列を読み取るために使用することもできます。
def iter_data(path):
with open(path) as data_file:
for line in data_file:
yield from line.split()
arr = np.fromiter(iter_data('data.txt'), int)
行列のサイズ (ファイルの最初の行から判断できます) がわかっている場合は、count
キーワード引数 を指定しnp.fromiter
て、関数が正確に適切な量のメモリを事前に割り当てられるようにすることができます。これにより、より高速になります。それがこれらの関数が行うことです:
def iter_data(fileobj):
for line in fileobj:
yield from line.split()
def read_triangular_array(path):
with open(path) as fileobj:
n = len(fileobj.readline().split())
count = int(n*(n+1)/2)
with open(path) as fileobj:
return np.fromiter(iter_data(fileobj), int, count=count)
これは、ファイルを 2 回開いて最初の行を読み取り、エントリの数を取得するため、少し作業が「無駄」になります。「改善」は、次のコードのように、最初の行を保存し、ファイルの残りの部分で反復子を使用してチェーンすることです。
from itertools import chain
def iter_data(fileobj):
for line in fileobj:
yield from line.split()
def read_triangular_array(path):
with open(path) as fileobj:
first = fileobj.readline().split()
n = len(first)
count = int(n*(n+1)/2)
data = chain(first, iter_data(fileobj))
return np.fromiter(data, int, count=count)
これらのアプローチはすべて
>>> arr
array([ 3., 5., 3., 5., 1., 8., 1., 6., 5., 8., 5., 8., 1.,
1., 6., 2., 9., 6., 4., 2., 0., 5., 2., 1., 0., 0.,
3., 2., 2., 5., 1., 0., 1., 0., 1., 3., 6., 3., 6.,
1., 4., 2., 4., 3., 7., 4., 0., 0., 1., 0., 1., 8.,
2., 1., 1.])
このコンパクトな表現で十分かもしれませんが、完全な正方行列が必要な場合は、適切なサイズのゼロ行列を割り当て、 を使用してコピーarr
するnp.triu_indices_from
か、 を使用できますscipy.spatial.distance.squareform
。
>>> from scipy.spatial.distance import squareform
>>> squareform(arr)
array([[ 0., 3., 5., 3., 5., 1., 8., 1., 6., 5., 8.],
[ 3., 0., 5., 8., 1., 1., 6., 2., 9., 6., 4.],
[ 5., 5., 0., 2., 0., 5., 2., 1., 0., 0., 3.],
[ 3., 8., 2., 0., 2., 2., 5., 1., 0., 1., 0.],
[ 5., 1., 0., 2., 0., 1., 3., 6., 3., 6., 1.],
[ 1., 1., 5., 2., 1., 0., 4., 2., 4., 3., 7.],
[ 8., 6., 2., 5., 3., 4., 0., 4., 0., 0., 1.],
[ 1., 2., 1., 1., 6., 2., 4., 0., 0., 1., 8.],
[ 6., 9., 0., 0., 3., 4., 0., 0., 0., 2., 1.],
[ 5., 6., 0., 1., 6., 3., 0., 1., 2., 0., 1.],
[ 8., 4., 3., 0., 1., 7., 1., 8., 1., 1., 0.]])