2017-06-16 3 views
0

データ列とレコードでテキストファイルを分析しようとしました。 私のファイル:このテキストファイルをcsvに変換するには?

Name  Surname Age Sex  Grade 
Chris  M.  14  M  4 
Adam  A.  17  M 
Jack  O.    M  8 

テキストファイルには空のデータがいくつかあります。上記のように。 ユーザー名と学年を表示したい:

import csv 

with open('launchlog.txt', 'r') as in_file: 
    stripped = (line.strip() for line in in_file) 
    lines = (line.split() for line in stripped if line) 
    with open('log.txt', 'w') as out_file: 
     writer = csv.writer(out_file) 
     writer.writerow(('Name', 'Surname', 'Age', 'Sex', 'Grade')) 
     writer.writerows(lines) 

log.txtという: "なし" という文字列を挿入し、データを空にするための方法

Chris,M.,14,M,4 
Adam,A.,17,M 
Jack,O.,M,8 

?たとえば :Pythonでこれを実行するための最良の方法だろう何

Chris,M.,14,M,4 
Adam,A.,17,M,None 
Jack,O.,None,M,8 

+1

固定幅フォーマットだ...それは働いていませんどのように**パンダ –

+0

に探してみては? – martineau

+0

出力csvファイルにはデータがありますが断片化はありません:http://prntscr.com/fkp8rs –

答えて

1

は、ここで、少なくともあなたの質問のサンプル・データ・ファイルに、あなたがやりたいように思わ™ピュアPythonで何か。

まず、列ヘッダー行の開始と終了のフィールド名のそれぞれと、ファイルの残りの行のそれぞれについて、使用される2番目のリストを取得するのと同じことを行います行内の各データ項目がどの列の下にあるかを決定します(次に、出力ファイルに書き込まれる行の適切な位置に配置されます)。

import csv 

def find_words(line): 
    """ Return a list of (start, stop) tuples with the indices of the 
     first and last characters of each "word" in the given string. 
     Any sequence of consecutive non-space characters is considered 
     as comprising a word. 
    """ 
    line_len = len(line) 
    indices = [] 
    i = 0 
    while i < line_len: 
     start, count = i, 0 
     while line[i] != ' ': 
      count += 1 
      i += 1 
      if i >= line_len: 
       break 
     indices.append((start, start+count-1)) 

     while i < line_len and line[i] == ' ': # advance to start of next word 
      i += 1 

    return indices 


# convert text file with missing fields to csv 
with open('name_grades.txt', 'rt') as in_file, open('log.csv', 'wt', newline='') as out_file: 
    writer = csv.writer(out_file) 
    header = next(in_file) # read first line 
    fields = header.split() 
    writer.writerow(fields) 

    # determine the indices of where each field starts and stops based on header line 
    field_positions = find_words(header) 

    for line in in_file: 
     line = line.rstrip('\r\n') # remove trailing newline 
     row = ['None' for _ in range(len(fields))] 
     value_positions = find_words(line) 
     for (vstart, vstop) in value_positions: 
      # determine what field the value is underneath 
      for i, (hstart, hstop) in enumerate(field_positions): 
       if vstart <= hstop and hstart <= vstop: # overlap? 
        row[i] = line[vstart:vstop+1] 
        break # stop looking 

     writer.writerow(row) 

ここではそれが作成さlog.csvファイルの内容です:

Name,Surname,Age,Sex,Grade 
Chris,C.,14,M,4 
Adam,A.,17,M,None 
Jack,O.,None,M,8 
1

利用パンダ:

import pandas 
data=pandas.read_fwf("file.txt") 

あなたdictionnaryを取得するには:

+0

パンダは自分のテキストファイルで作業していません。 –

+0

これはあなたが提供した例です。 – baloo

0

私は私の上にbalooの答えを使用します - しかし、あなたはちょうどあなたのコードが間違っていた場所の感触を取得したい場合以下の解決法はほとんどが機能します(Gradeフィールドの書式設定に問題がありますが、それを解決できると確信しています)。コードにいくつかの印刷ステートメントを追加してマイニングすると、違いを取り出せるはずです。

インポートCSV

<Old Code removed in favor of new code below> 

編集:私は今、あなたの難しさを参照してください。以下のコードを試してみてください。私は今日時間がないので、あなたはprintステートメントがどこにあるライターの部分に記入する必要がありますが、空のフィールドをNoneに置き換える要求を満たします。パンダを使用せずに

import csv 

with open('Test.txt', 'r') as in_file: 
    with open('log.csv', 'w') as out_file: 
     writer = csv.writer(out_file) 
     lines = [line for line in in_file] 
     name_and_grade = dict() 
     for line in lines[1:]: 
      parts = line[0:10], line[11:19], line[20:24], line[25:31], line[32:] 
      new_line = list() 
      for part in parts: 
       val = part.replace('/n','') 
       val = val.strip() 
       val = val if val != '' else 'None' 
       new_line.append(val) 
      print(new_line) 
0



あなたのコメントに基づいて編集された、私はハードあなたのデータに基づいて、このソリューションをコード化されました。これは、行がSurname列を持たないためには機能しません。
NameGradeは、これらの2つの列だけが必要なので書きました。

o = open("out.txt", 'w') 
with open("inFIle.txt") as f: 
    for lines in f: 
     lines = lines.strip("\n").split(",") 
     try: 
      grade = int(lines[-1]) 
      if (lines[-2][-1]) != '.': 
       o.write(lines[0]+","+ str(grade)+"\n") 
     except ValueError: 
      print(lines) 
o.close() 
関連する問題