2016-08-02 2 views
0

Мы застреваем, пытаясь найти способ разобрать хитрый текстовый файл, созданный с помощью PEST-анализа с использованием Python. Он показывает измерения 63 различных переменных для более чем 30 000 наблюдений. Вот пример вывода (3 /> 30000 показаны)Python parse txt file, вывод PEST, jacobian.txt

      cmfa   cmfb   cmfc   cmfd   cmla   cmlb   cmlc   cmld 
          cmle   cgfa   cgfb   cgfc   cgfd   cgfe   dgfa   dgfb 
          dgfc   dgfd   icfa   icfb   icfc   icfd   vawa   vawb 
          vawc   vawd   vawe   vawf   vswa   vswb   vswc   vswd 
          vswe   chfa   chfb   chfc   chfd   chfe   cgwa   cgwb 
          cgwc   cgwd   cgwe   crta   crtb   crtc   crtd   crte 
          icha   ichb   ichc   ichd   iche   csea   cseb   csec 
          csed   csee   csef   caqa   caqb   crsa   crsb 

       0 -1.900000E-03 1.080000E-02 3.150000E-02 0.00000  0.00000  0.00000  0.00000  -3.020000E-02 
         0.00000  -1.870000E-02 0.00000  4.600000E-03 0.00000  0.00000  0.00000  4.510000E-02 
         0.00000  0.00000  3.650000E-02 -7.000000E-03 -2.100000E-03 -2.000000E-04 3.200000E-03 8.000000E-03 
        -7.000000E-04 -1.500000E-02 0.00000  4.800000E-03 1.900000E-03 4.000000E-04 2.500000E-03 2.500000E-03 
        -1.400000E-02 0.00000  0.00000  0.00000  0.00000  0.00000  -3.200000E-03 -8.060000E-02 
        -0.126500  0.298400  0.00000  0.00000  0.00000  0.00000  0.00000  8.000000E-04 
        -1.900000E-03 1.400000E-03 0.00000  0.00000  -3.200000E-03 0.00000  0.00000  0.00000  
         0.00000  0.00000  0.00000  0.00000  0.00000  -1.200000E-02 1.930000E-02 

       1 -1.800000E-03 1.140000E-02 1.850000E-02 0.00000  0.00000  0.00000  0.00000  -2.600000E-02 
         0.00000  -8.200000E-03 0.00000  1.200000E-03 0.00000  0.00000  0.00000  0.00000  
         0.00000  0.00000  2.560000E-02 -6.100000E-03 -1.100000E-03 0.00000  3.000000E-03 7.400000E-03 
        -7.000000E-04 -1.410000E-02 0.00000  5.000000E-03 1.900000E-03 3.000000E-04 2.300000E-03 2.300000E-03 
        -1.330000E-02 0.00000  0.00000  0.00000  0.00000  0.00000  -3.400000E-03 -8.410000E-02 
        -0.123500  0.301900  0.00000  0.00000  0.00000  0.00000  0.00000  1.200000E-03 
        -2.000000E-03 1.400000E-03 0.00000  0.00000  -3.200000E-03 0.00000  0.00000  0.00000  
         0.00000  0.00000  0.00000  0.00000  0.00000  -1.280000E-02 2.050000E-02 

       2 -3.300000E-03 6.500000E-03 4.040000E-02 0.00000  0.00000  0.00000  0.00000  -7.060000E-02 
        4.840000E-02 -0.112500  0.110300  0.00000  0.00000  0.00000  1.10330  0.00000  
         0.00000  0.00000  3.940000E-02 -8.500000E-03 -1.120000E-02 6.600000E-03 5.700000E-03 1.430000E-02 
        -1.300000E-03 -2.470000E-02 0.00000  3.700000E-03 2.200000E-03 5.000000E-04 4.300000E-03 4.500000E-03 
        -2.250000E-02 0.00000  0.00000  0.00000  0.00000  0.00000  -2.000000E-03 -5.840000E-02 
        -0.157300  0.292400  0.00000  0.00000  0.00000  0.00000  0.00000  -3.600000E-03 
        -1.700000E-03 1.200000E-03 0.00000  0.00000  -3.400000E-03 0.00000  0.00000  0.00000  
         0.00000  0.00000  0.00000  0.00000  0.00000  -7.400000E-03 1.180000E-02 

       3 -2.200000E-03 1.040000E-02 3.500000E-02 0.00000  0.00000  0.00000  0.00000  -4.390000E-02 
         0.00000  -3.170000E-02 2.590000E-02 0.00000  0.00000  0.00000  0.259400  0.00000  
         0.00000  0.00000  3.920000E-02 -1.030000E-02 -3.500000E-03 1.500000E-03 3.600000E-03 9.000000E-03 
        -9.000000E-04 -1.680000E-02 0.00000  4.700000E-03 2.000000E-03 3.000000E-04 2.700000E-03 2.800000E-03 
        -1.560000E-02 0.00000  0.00000  0.00000  0.00000  0.00000  -3.200000E-03 -7.920000E-02 
        -0.131600  0.302200  0.00000  0.00000  0.00000  0.00000  0.00000  3.000000E-04 
        -2.000000E-03 1.300000E-03 0.00000  0.00000  -3.300000E-03 0.00000  0.00000  0.00000  
         0.00000  0.00000  0.00000  0.00000  0.00000  -1.180000E-02 1.880000E-02 

буквенные коды (СМИД, CMFB и т.д.) имена 63 переменных. Каждая из переменных буквенного кода относится к числу в одной и той же позиции для каждого из следующих текстовых блоков.

Первый блок чисел для наблюдения 0, следующий блок для наблюдения 1 и т. Д. Для более чем 30 000 наблюдений.

Мы хотим найти способ превратить это в текстовый файл (желательно .csv). В случае с моим текстовым примером у него будет 63 столбца и 3 строки (+1 для идентификатора). Каждая колонка будет называться с соответствующим буквенным кодом (СМИД и т.д.)

Если возможно, мы хотели бы, чтобы это запустить на файл с любым количеством столбцов и любого числа наблюдений

+0

Что вы пытаетесь до сих пор? Простое решение: вы можете использовать текстовый процессор с регулярными выражениями, например vi (unix) или notepad ++ (win), и заменять отдельные символы новой строки на пробелы или вкладки, чем заменять пробелы или вкладки запятыми. –

ответ

1

А способ разобрать файл, который вы предоставили (независимо от количества строк в файле), используя простой питон, лучше реализации может быть сделана с помощью регулярных выражений, но я хотел бы оставить его для вас, чтобы попытаться дальше:

#Importing required libraries 
import numpy as np 
import csv 

#Open input file 
with open('input.txt','rb') as f: 
    line = f.read().splitlines() 

#Read file and do some parsing 
line2 = [] 
for l in line: 
    z = l.split(" ") 
    l2 = [] 
    for val in z: 
     if not(val==''): 
      l2.append(val) 
    if len(l2)==9: 
     line2.append(l2[1:9]) 
    elif len(l2)==7 or len(l2)==8: 
     line2.append(l2) 

#Remove unnecessary rows and do type conversion to float 
pl = np.arange(0,len(line2)+1,8) 
line3 = [] 
for i in np.arange(0,len(pl)-1): 
    z = line2[pl[i]:pl[i+1]] 
    z2 = [item for sublist in z for item in sublist] 
    if i==0: 
     line3.append(z2) 
    else: 
     line3.append([float(i) for i in z2]) 

#Write to output file 
with open('output.csv','wb') as f: 
    wr = csv.writer(f) 
    for row in line3: 
     wr.writerow(row) 

в случае, если вы хотите сохранить индексы:

#Importing required libraries 
import numpy as np 
import csv 

#Open input file 
with open('input.txt','rb') as f: 
    line = f.read().splitlines() 

#Read file and do some parsing 
line2 = [] 
for l in line: 
    z = l.split(" ") 
    l2 = [] 
    for val in z: 
     if not(val==''): 
      l2.append(val) 
    if not(len(l2)==0): 
     line2.append(l2) 

#Remove unnecessary rows and do type conversion to float 
pl = np.arange(0,len(line2)+1,8) 
line3 = [] 
for i in np.arange(0,len(pl)-1): 
    if i==0: 
     z = line2[pl[i]:pl[i+1]] 
     z2 = [item for sublist in z for item in sublist] 
     line3.append(['']+z2) 
    else: 
     z = line2[pl[i]:pl[i+1]] 
     z2 = [item for sublist in z for item in sublist] 
     line3.append([float(i) for i in z2]) 

#Write to output file 
with open('output.csv','wb') as f: 
    wr = csv.writer(f) 
    for row in line3: 
     wr.writerow(row) 
+0

Спасибо, Гаурав! Это делает именно то, о чем я просил. Я забыл спросить, может ли и номер наблюдения быть транскрибирован (в этом случае 0,1,2,3) в качестве первого столбца в csv. Было бы возможно иметь это и в csv? – bigCow

+0

Отредактировано с включенным номером. Ура !! Пожалуйста, отметьте как правильно, если вы считаете, что все в порядке. –

+0

Опять же, вы ответили точно, что я спросил. Моя ошибка, я забыл спросить, можно ли также назвать новое поле ID как «ID» или «FID» или что-то вроде этого. – bigCow

0

Вы можете использовать mmap и регулярное выражение для анализа файла без необходимости считывания всего файла в память.

Что-то вроде:

import re 
import mmap 
import os 

size=os.stat(fn_in).st_size 

with open(fn_in, "r") as fin, open(fn_out, "w") as fout: 
    data = mmap.mmap(fin.fileno(), size, access=mmap.ACCESS_READ) 
    for idx, m in enumerate(re.finditer(r"(.*?)(?:(?:^\s*$)|\Z)", data, re.M | re.S)): 
     block=m.group(0).strip() 
     if not block: 
      continue 
     if idx==0: 
      fout.write("O_N,"+",".join(block.split())+"\n") 
     else: 
      fout.write(",".join(block.split())+"\n")