6

私は、誰かが有限要素メッシュをある形式から別の形式に変換するのを手伝うことを志願しました (i-deas *.unv から Alberta へ)。NumPy を使用してメッシュの追加整形を行いましたが、生のテキスト ファイル データを NumPy 配列に読み込む際に問題が発生しています。genfromtxt と loadtxt を試しましたが、これまでのところ成功していません。

いくつかの詳細:

1) すべてのグループは、ヘッダーとフッターのフラグ " -1" で区切られています。

2) NODE グループには、独自の行にヘッダー "2411" があります。このグループから 1 行おきに読み取りたいのは、4 つの整数を含む各行をスキップすることですが、3 つの Fortran 倍精度数を含む行を読み取ります。

3) ELEMENT 接続グループには、独自の行にヘッダー "2412" があります。すべてのデータは整数で、最初の 4 列のみを読み取る必要があります。2 つと 3 つのノード要素の値が欠落しているため、NumPy 配列には空のスロットがいくつかあります。

4) "2477" ノード グループ 正規表現を使用して、読み取る行を見つけることができると思います。

5) 実際のデータ ファイルには約 100 万行のテキストがあるため、可能であれば (または NumPy がすばやく読み取るために行うことを) ベクトル化することを切望しています。

情報が多すぎて申し訳ありません。ありがとうございます。

以下の行は、*.unv テキスト ファイル形式の一部のサンプルです。

    -1
  2411
  146303         1         1        11
  6.9849462399269246D-001  8.0008842847097805D-002  6.6360238055630028D-001
  146304         1         1        11
  4.1854795755893875D-001  9.1256034628308313D-001  3.5725496189239300D-002
  146305         1         1        11
  7.5541258490349616D-001  3.7870257739063029D-001  2.0504544370783115D-001
  146306         1         1        11
  2.7637569971086767D-001  9.2829777518336010D-001  1.3757239038663285D-001
   -1
   -1
 2412
     9        21         1         0         7         2
     0         0         0
     1         9
    10        21         1         0         7         2
     0         0         0
     9        10
  1550        91         6         0         7         3
   761      3685      2027
  1551        91         6         0         7         3
   761      2380      2067
 39720       111         1         0         7         4
 71854     59536     40323     73014
 39721       111         1         0         7         4
 45520     48908    133818    145014
   -1
   -1
   2477
     1         0         0         0         0         0         0      3022
PERMANENT GROUP1
     7         2         0         0         7         3         0         0
     7         8         0         0         7         7         0         0
     7       147         0         0         7       148         0         0
     2         0         0         0         0         0         0      2915
PERMANENT GROUP2
     7         1         0         0         7         5         0         0
     7         4         0         0         7         6         0         0
     7         9         0         0         7        11         0         0
   -1
4

1 に答える 1

5

numpyメソッドはgenfromtxtloadtxtデータが非常に特殊な構造(ノードによって異なる)であるため、ファイル全体に適用するのはかなり困難です。したがって、次の戦略をお勧めします。

  • ファイルを1行ずつ読み取り、その行を分析して、現在のノードを特定してください。

  • データが少ないノードにいる場合(たとえば、交互の行を読み取る必要があるため、継続的に読み取ることができない場合)、行ごとに読み取り、行を処理します。

  • データが多いセクション(「実際のデータ」があるセクションなど)に到達したら、次のようにnumpysfromfileメソッドを使用してデータを読み込みます。

    mydata = np.fromfile(fp, sep=" ", dtype=int, count=number_of_elements)
    mydata.shape = (100000, 3)    # Reshape it to the desired shape as fromfile
                                  # returns a 1D array.
    

このようにして、行ごとの処理の柔軟性と、大量のデータをすばやく読み取って変換する機能を組み合わせます。

更新:重要なのは、ファイルを開いて1行ずつ読み取り、大量のデータがある場所に到着したら、ファイル記述子をfromfileに渡すことです。

簡略化した例の下:

import numpy as np

fp = open("test.dat", "r")
line = fp.readline()
ndata = int(line.strip())
data = np.fromfile(fp, count=ndata, sep=" ", dtype=int)
fp.close()

test.datこれにより、次のような内容のファイルからデータが読み取られます。

10
1 2 3 4 5
6 7 8 9 10

最初の行は、で明示的に読み取られfp.read()、処理され(読み取られる整数の数が決定されます)np.fromfile()、適切なデータのチャンクを読み取って1D配列に格納しdataます。

UPDATE2:または、テキスト全体をバッファーに読み込んでから、大量のデータの開始位置と終了位置を決定し、np.fromstring直接変換することもできます。

fp = open("test.dat", "r")
txt = fp.read()
fp.close()
# Now determine starting and end positions (startpos, endpos)
# ..
# pass text that portion of the text to the fromstring function.
data = np.fromstring(txt[startpos:endpos], dtype=int, sep=" ")

または、1つの正規表現として簡単に定式化できる場合はfromregex()、ファイルで直接使用できます。

于 2013-02-19T09:04:18.613 に答える