1

テキスト ファイルからテキストを読み取り、そのテキストを再フォーマットして別のテキスト ファイルに書き込みます。

私が読んでいるテキストは次のとおりですtestFile.txt

                  *******************************
                  *  Void Fractions in the Bed  *
                  *******************************

     Z(m)    MIN.FLUIDIZ.  EMULSION    TOTAL

0.0000E+00  0.4151E+00  0.8233E+00  0.8233E+00
0.1000E-09  0.4151E+00  0.8233E+00  0.8233E+00
0.1000E-05  0.4151E+00  0.8233E+00  0.8233E+00
0.2000E-05  0.4151E+00  0.8233E+00  0.8233E+00
0.1251E+01  0.4151E+00  0.9152E+00  0.9152E+00
0.1301E+01  0.4151E+00  0.9152E+00  0.9152E+00
0.1333E+01  0.4151E+00  0.9152E+00  0.9152E+00


               *************************************
               *  Void Fractions in the Freeboard  *
               *************************************

     Z(m)    VOID FRACTION

0.1333E+01  0.9992E+00
0.1333E+01  0.9992E+00
0.1333E+01  0.9992E+00
0.1333E+01  0.9992E+00
0.3533E+01  0.9992E+00
0.3633E+01  0.9992E+00
0.3733E+01  0.9992E+00
0.3833E+01  0.9992E+00
0.3933E+01  0.9992E+00
0.4000E+01  0.9992E+00


           *********************************************
           *  Superficial Velocities in the Bed (m/s)  *
           *********************************************

     Z(m)    MIN.FLUIDIZ.  ACTUAL

0.0000E+00  0.1235E+00  0.4911E+01
0.1000E-09  0.1235E+00  0.4911E+01
0.1000E-05  0.1235E+00  0.4911E+01
0.2000E-05  0.1235E+00  0.4911E+01
0.3000E-05  0.1235E+00  0.4911E+01
0.1151E+01  0.1235E+00  0.4915E+01
0.1201E+01  0.1235E+00  0.4915E+01
0.1251E+01  0.1235E+00  0.4915E+01
0.1301E+01  0.1235E+00  0.4915E+01
0.1333E+01  0.1235E+00  0.4915E+01

以下は、テキスト ファイルを解析するための Python コードです。

openFile = open('testFile.txt','r')

groupOneFile = open('groupOneFile.csv','w')
groupTwoFile = open('groupTwoFile.csv','w')
groupThreeFile = open('groupThreeFile.csv','w')

idx = 0;
firstIdx = 0;
secondIdx = 0;
thirdIdx = 0;

for line in openFile:

    # first group
    if '*  Void Fractions in the Bed  *' in line:
        print line
        firstIdx = idx

    if idx in range(firstIdx+5,firstIdx+43):
        line = line.lstrip()
        line = line.replace('  ',',')
        groupOneFile.write(line)

    # second group
    if '*  Void Fractions in the Freeboard  *' in line:
        print line
        secondIdx = idx

    if idx in range(secondIdx+5,secondIdx+43):
        line = line.lstrip()
        line = line.replace('  ',',')
        groupTwoFile.write(line)        

    # third group
    if '*  Superficial Velocities in the Bed (m/s)  *' in line:
        print line
        thirdIdx = idx

    if idx in range(thirdIdx+5,thirdIdx+43):
        line = line.lstrip()
        line = line.replace('  ',',')
        groupThreeFile.write(line)

    idx += 1

openFile.close()

groupOneFile.close()
groupTwoFile.close()
groupThreeFile.close()

groupOneFileには、次のデータが含まれている必要があります。

0.0000E+00,0.4151E+00,0.8233E+00,0.8233E+00
0.1000E-09,0.4151E+00,0.8233E+00,0.8233E+00
0.1000E-05,0.4151E+00,0.8233E+00,0.8233E+00
0.2000E-05,0.4151E+00,0.8233E+00,0.8233E+00
0.1251E+01,0.4151E+00,0.9152E+00,0.9152E+00
0.1301E+01,0.4151E+00,0.9152E+00,0.9152E+00
0.1333E+01,0.4151E+00,0.9152E+00,0.9152E+00

groupTwoFileには次のものが必要です。

0.1333E+01,0.9992E+00
0.1333E+01,0.9992E+00
0.1333E+01,0.9992E+00
0.1333E+01,0.9992E+00
0.3533E+01,0.9992E+00
0.3633E+01,0.9992E+00
0.3733E+01,0.9992E+00
0.3833E+01,0.9992E+00
0.3933E+01,0.9992E+00
0.4000E+01,0.9992E+00

についても同様groupThreeFileです。

本文ファイルの読み込みと他のファイルへのデータの書き込みは正常に動作しています。問題は、 に書き込まれるデータがgroupOneFile、他のファイルgroupTwoFileおよびの先頭にも書き込まれることですgroupThreeFile。どうすればこれを防ぐことができますか?

4

4 に答える 4

1

あなたは私の提案を求めたので、ここにあります

from itertools import groupby, product

groups = {'*  Void Fractions in the Bed  *': 'groupOneFile.csv',
          '*  Void Fractions in the Freeboard  *': 'groupTwoFile.csv',
          '*  Superficial Velocities in the Bed (m/s)  *': 'groupThreeFile.csv'}

fname = None

with open('testFile.txt','r') as fin:
    for k, group in groupby(fin, lambda x:x[0].isspace()):
        if k:
            for i, g in product(group, groups):
                if g in i:
                    fname = groups[g]
                    break
        else:
            with open(fname, 'w') as fout:
                fout.writelines(','.join(s.split())+'\n' for s in group)
于 2013-11-13T00:23:46.127 に答える
1

それを機能させるには、初期化するだけです

firstIdx = 1000000
secondIdx = 1000000
thirdIdx = 1000000

問題は、それらを設定すると0、最初の行がすべてのグループの範囲内になることです。

ただし、このコードは非常に非効率的であることに注意してください...より良いアプローチは次のとおりです。

outputFile = None

for line in openFile:
    if '*  Void Fractions in the Bed  *' in line:
        idx = 0; outputFile = groupOneFile
    elif '*  Void Fractions in the Freeboard  *' in line:
        idx = 0; outputFile = groupTwoFile
    elif '*  Superficial Velocities in the Bed (m/s)  *' in line:
        idx = 0; outputFile = groupThreeFile

    if outputFile and 5 <= idx < 43:
        line = line.lstrip()
        line = line.replace('  ',',')
        outputFile.write(line)

    idx = idx + 1

Pythonでは、テストを実行するたびに、すべての要素のチェックが行われます (または Python 2.x では、 からまでif x in range(a, b):のすべての整数の実際のリストが作成されます)。テストを のように書く方がはるかに優れています。ab-1if a <= x < b:

2.5 in range(0, 10)false を返すことにも注意してください(もちろん0 <= 2.5 < 10true ですが)。

Python にはswitchステートメントはありませんが、代わりにディスパッチ テーブルを作成できます。

filemap = [('*  Void Fractions in the Bed  *', groupOneFile),
           ('*  Void Fractions in the Freeboard  *', groupTwoFile),
           ('*  Superficial Velocities in the Bed (m/s)  *', groupThreeFile)]

outputFile = None
for line in openFile:
    for tag, file in filemap:
        if tag in line:
            idx = 0
            outputFile = file
    if outputFile and 5 <= idx < 43:
        outputFile.write(line)
    idx += 1

(テストの代わりに) 完全一致が可能な場合はin、辞書を使用してさらに改善することができます。

filemap = {'*  Void Fractions in the Bed  *': groupOneFile,
           '*  Void Fractions in the Freeboard  *': groupTwoFile,
           '*  Superficial Velocities in the Bed (m/s)  *': groupThreeFile)}

outputFile = None
for line in openFile:
    f = filemap.get(line.strip())
    if f:
        # Found a new group header, switch output file
        idx = 0
        outputFile = f
    if outputFile and 5 <= idx < 43:
        outputFile.write(line)
    idx += 1
于 2013-11-13T00:02:21.933 に答える
0
with open("testFile.txt") as f:
  lines = list(f)

firstIdx = secondIdx = thirdIdx = None
for x, line in enumerate(lines):
  if "*  Void Fractions in the Bed  *" in line:
    firstIdx = x
  elif "*  Void Fractions in the Freeboard  *" in line:
    secondIdx = x
  elif "*  Superficial Velocities in the Bed (m/s)  *" in line:
    thirdIdx = x

def write_lines(start, end, filename):
  with open(filename, "w") as f:
    for line in lines[start:end]:
      f.write(line.replace("  ", ","))

if firstIdx is not None:
  write_lines(firstIdx + 5, firstIdx + 43, "groupOneFile.csv")
if secondIdx is not None:
  write_lines(secondIdx + 5, secondIdx + 43, "groupTwoFile.csv")
if thirdIdx is not None:
  write_lines(thirdIdx + 5, thirdIdx + 43, "groupThreeFile.csv")
于 2013-11-13T00:08:21.567 に答える
0

secondIdx0からthirdIdx始まります。これif idx in range(secondIdx+5,secondIdx+43):は、ファイルの先頭に近い行でトリガーしていることを意味します。

これを修正するには、よりステートフルなセットアップに書き直すか ( を読むときVoid Fractions in the Bed、新しい見出しが見つかるまで最初のファイルに書き込むなど)、単にIdxs を初期化するだけ-100です。

于 2013-11-13T00:02:50.137 に答える