2017-06-30 12 views
1

私はこのようになりますファイルがあります:np.loadtxt

some text 
the grids are 
     3 x 3 

more text 

matrix marker 1 1 
3 2 4 
7 4 2 
9 1 1 

new matrix 2 4 
9 4 1 
1 3 4 
4 3 1 

new matrix 3 3 
7 2 1 
1 3 4 
2 3 2 

..ファイルは、続けて同じように表示されるいくつかの3x3の行列とを。 IDは特に重要ではありませんが、各マトリックスは固有のIDを持つテキストで始まります。私はこれらの行列の行列を作りたいと思う。私はそれを行うためにloadtxtを使用することはできますか?

これは私の最高の試みです。このコードの6は、6から始まり、行列の行数で増分する反復変数に置き換えることができます。私はskiprowsがリストを受け入れると思ったが、明らかに整数だけを受け入れる。

np.loadtxt(fl, skiprows = [x for x in range(nlines) if x not in (np.array([1,2,3])+ 6)]) 

TypeError         Traceback (most recent call last) 
<ipython-input-23-7d82fb7ef14a> in <module>() 
----> 1 np.loadtxt(fl, skiprows = [x for x in range(nlines) if x not in (np.array([1,2,3])+ 6)]) 

/usr/local/lib/python2.7/site-packages/numpy/lib/npyio.pyc in loadtxt(fname, dtype, comments, delimiter, converters, skiprows, usecols, unpack, ndmin) 
    932 
    933   # Skip the first `skiprows` lines 
--> 934   for i in range(skiprows): 
    935    next(fh) 
    936 
+0

単一の呼び出しは、それを行うことはできません。自分のファイル 'readlines'を使ってファイルを読み込み、数値の単純なブロック(一貫した数の列を持つ行)を' loadtxt'に渡すか、あるいは直接解析することをお勧めします。 9個の数字のブロックは解析が容易でなければなりません。 – hpaulj

+0

@hpauljどのようにして数値のブロックを 'loadtxt'に渡すのですか?あなたの助言は本質的に投稿された試行で何をしようとしています。 – kilojoules

+0

また、これは単純な問題であることに注意してください。私の実際のケースは30x30行列です。 – kilojoules

答えて

2

たぶん私は誤解していますが、3x3の行列の前の行を一致させることができるならば、あなたはloadtxtに供給するジェネレータを作成することができます。

import numpy as np 

def get_matrices(fs): 
    while True: 
     line = next(fs) 
     if not line: 
      break 
     if 'matrix' in line: # or whatever matches the line before a matrix 
      yield next(fs) 
      yield next(fs) 
      yield next(fs) 


with open('matrices.dat') as fs: 
    g = get_matrices(fs) 
    M = np.loadtxt(g) 

M = M.reshape((M.size//9, 3, 3)) 
print(M) 

あなたはそれを養う場合:

some text 
the grids are 
     3 x 3 

more text 

matrix marker 1 1 
3 2 4 
7 4 2 
9 1 1 

new matrix 2 4 
9 4 1 
1 3 4 
4 3 1 

new matrix 3 3 
7 2 1 
1 3 4 
2 3 2 

new matrix 7 6 
1 0 1 
2 0 3 
0 1 2 

行列の配列を取得します。

[[[ 3. 2. 4.] 
    [ 7. 4. 2.] 
    [ 9. 1. 1.]] 

[[ 9. 4. 1.] 
    [ 1. 3. 4.] 
    [ 4. 3. 1.]] 

[[ 7. 2. 1.] 
    [ 1. 3. 4.] 
    [ 2. 3. 2.]] 

[[ 1. 0. 1.] 
    [ 2. 0. 3.] 
    [ 0. 1. 2.]]] 
また

、あなただけのyieldに、彼らは、整数の3×3の行列から列かもしれないように見えるすべての行をしたい場合は、正規表現にマッチ:

import re 

def get_matrices(fs): 
    while True: 
     line = next(fs) 
     if not line: 
      break 
     if re.match('\d+\s+\d+\s+\d+', line): 
      yield line 
1

あなたは手順を使用するように処理ワークフローを変更する必要があります。numpy.loadtxtを呼び出した後、最初のご希望の行列に対応する部分文字列を抽出します。これを行うには、素晴らしい方法があります:

  1. reで始まりと終わりを検索します。
  2. この範囲内の荷重行列
  3. 範囲をリセットして続行します。その後

    start = re.compile("\w+\s+matrix\s+(\d+)\s+(\d+)\n") 
    end = re.compile("\n\n") 
    

    あなたが開始/終了のペアを検索し、各行列のテキストを読み込むことができ、:あなたはこのような正規表現を使用できるよう

あなたの行列マーカーは、多様であるように見える

この場合、アイデア

import io 
import numpy as np 

# read our data 
data = open("/path/to/file.txt").read() 

def load_matrix(data, *args): 
    # find start and end bounds 
    s = start.search(data) 
    if not s: 
     # no matrix leftover, return None 
     return None 
    e = end.search(data, s.end()) 
    e_index = e.end() if e else len(data) 

    # load text 
    buf = io.StringIO(data[s.end(): e_index]) 
    matrix = np.loadtxt(buf, *args) # add other args here 

    # reset our buffer 
    data = data[e_index:] 

    return matrix 

、私のための正規表現のマーカー行列の先頭には、行列の次元として捕捉グループ(\d+)がありますので、望むならば、行列の表現はMxNになります。リストアイテムはまた、行の "matrix"という単語を持つアイテムを検索し、任意の先頭のテキストと最後に空白で区切られた2つの数字で検索します。

「\ n \ n」グループが2つ、または改行が2つあります(Windowsの行末がある場合は、「\ r」も考慮する必要があります)。この

を自動化

今、私たちは一つのケースを見つけるための方法を持っていることを、あなたがする必要があるすべては、あなたはまだ試合を取得しながら、これを繰り返すと行列のリストを移入です。

matrices = [] 

# read our data 
data = open("/path/to/file.txt").read() 

while True: 
    result = load_matrix(data, ...)  # pass other arguments to loadtxt 
    if not result: 
     break 
    matrices.append(result) 
関連する問題