2014-12-18 2 views
0

Я пытаюсь разобрать файл csv, но кажется, что я пропустил что-то основное и не могу понять. Каждое исходное значение csv содержит строку в {}, включающую несколько параметров, отсортированных случайным образом, например, в приведенном ниже примере.синтаксический анализ файла csv в модуле python и csv

Timestamp,Session Index,Event,Description,Version,Platform,Device,User ID,Params, 
"Dec 03, 2014 01:30 AM",1,NoRegister,,1.4.0,iPhone,Apple iPhone 5s (GSM),,{}, 
"Dec 03, 2014 01:30 AM",2,HomeTab,Which tab the user viewed ,1.4.0,iPhone,Apple iPhone 5s (GSM),,{ UserID : 36875; tabName : QuickAndEasy}, 
"Dec 03, 2014 01:30 AM",3,UserRecipeOverview,How many users go to Overview of a recipe?,1.4.0,iPhone,Apple iPhone 5s (GSM),,{ RecipeID : 1488; UserID : 36875}, 

Мой код выглядит следующим образом, но я получаю сообщение об ошибке, что я не понимаю:

counter = 0 

mappedLines = {} 

import csv 
with open ('test.csv', 'r') as f: 
    reader = csv.reader (f) 

    for line in reader: 
     counter = counter + 1 
     lineDict = {} 
     line = line.replace("{","") 
     line = line.replace("}","") 
     line = line.strip() 
     fieldPairs = line.split(";") 

     for pair in fieldPairs: 
      fields = pair.split(":") 
      key = fields[0].strip() 
      value = fields[1].strip() 
      lineDict[key] = value 

     mappedLines[counter] = lineDict 

def printFields(keys, lineSets): 
    output_line = "" 
    for key in keys: 
     if key in lineSets: 
      output_line = output_line + lineSets[key] + "," 
     else: 
      output_line += "," 
    print output_line[0:len(output_line) - 1] 

fields = ["UserID", "tabName", "RecipeID", "type", "searchWord", "isFromLabel"] 

for key in range(1,len(mappedLines) + 1): 
    lineSets = mappedLines[key] 
    printFields(fields,lineSets) 

Вот Traceback:

Traceback (most recent call last): 
    File "testV3.py", line 14, in <module> 
     line = line.replace("{","") 
AttributeError: 'list' object has no attribute 'replace' 

EDIT:

Я m теперь triyng, чтобы включить функцию записи для сохранения вывода в новый файл csv со следующим. csv записывает только заголовки и в столбце.

import csv 


def printfields(keys, linesets): 
    output_line = "" 
    for key in keys: 
     if key in linesets: 
      output_line += linesets[key] + "," 
     else: 
      output_line += "," 
    print output_line 


def csv_writer(reader, path): 
    """ 
    write reader to a csv file path 
    """ 
    with open(path, "wd") as csv_file: 
     writer = csv.writer(csv_file, delimiter=",") 
     for line1 in line: 
      if line1 in path 
      writer.writerow(line1) 

if __name__ == "__main__": 
    fields = [ 
     "UserID", "tabName", "RecipeID", "type", "searchWord", "isFromLabel", "targetUID" 
    ] 
    mappedLines = {} 
    with open('test.csv', 'r') as f: 
     reader = csv.DictReader(f) 
     for line in reader: 
      fieldPairs = [ 
       p for p in 
       line['Params'].strip().strip('}').strip('{').strip().split(';') 
       if p 
      ] 
      lineDict = { 
       pair.split()[0].strip(): pair.split(':')[1].strip() 
       for pair in fieldPairs 
      } 
      mappedLines[reader.line_num] = lineDict 
     path = "output.csv" 
     csv_writer(reader, path) 

    for key in sorted(mappedLines.keys()): 
     linesets = mappedLines[key] 
     printfields(fields, linesets) 
+0

Я решил ваш первоначальный вопрос, а imho ваш EDIT квалифицируется как отдельный вопрос. Если вы согласитесь, не могли бы вы переместить вашу дополнительную часть редактирования вашего вопроса в новый вопрос и решить этот вопрос в ответ? – dopstar

+0

Привет @dopstar, Спасибо за помощь, комментарии и рекомендации при использовании переполнения стека. Как вы, вероятно, заметили, я все еще изучаю хорошие практики, когда вы получаете помощь от сообщества. ваша помощь помогает! Теперь я создал новый пост http://stackoverflow.com/questions/27815100/parsing-and-saving-csv-file-in-python-and-csv-module, включая мои изменения, чтобы вы могли ответить на него. Благодаря! – mmarboeuf

ответ

0

Я переставить код и изменил его. Изменения состоят в том, что он использует csv.DictReader, а переменная счетчика больше не используется. и функция range в цикле for больше не используется.

import csv 


def printFields(keys, lineSets): 
    output_line = "" 
    for key in keys: 
     if key in lineSets: 
      output_line += lineSets[key] + "," 
     else: 
      output_line += "," 
    print output_line 


if __name__ == "__main__": 
    fields = [ 
     "UserID", "tabName", "RecipeID", "type", "searchWord", "isFromLabel" 
    ] 
    mappedLines = {} 
    with open('test.csv', 'r') as f: 
     reader = csv.DictReader(f) 
     for line in reader: 
      fieldPairs = [ 
       p for p in 
       line['Params'].strip().strip('}').strip('{').strip().split(';') 
       if p 
      ] 
      lineDict = { 
       pair.split()[0].strip(): pair.split(':')[1].strip() 
       for pair in fieldPairs 
      } 
      mappedLines[reader.line_num] = lineDict 

    for key in sorted(mappedLines.keys()): 
     lineSets = mappedLines[key] 
     printFields(fields, lineSets) 
+0

Спасибо! Это работало как шарм. все еще изо всех сил пытаюсь написать вывод в файл csv, хотя – mmarboeuf

+0

Итак, теперь я пытаюсь записать ouptupt в файл csv, но я получаю только заголовки в файле csv – mmarboeuf

+0

. Вы бы тогда положили этот ответ как можно более полезным и после этого создайте отдельный вопрос для вашей дополнительной части? – dopstar

1

line представляет собой список, содержащий клетки текущей строки. Чтобы получить доступ к одному из них, использовать цикл:

for cell in line: 
    cell.replace(...) 
+0

Привет, спасибо за отзыв, но я сожалею, что до сих пор не понимаю. Я уже использую цикл, и я не знаю, что делать с твоим. Не могли бы вы подробнее объяснить, как мне добавить/заменить другой цикл? Tks! M. – mmarboeuf

+0

Как я писал: 'line' - это массив, а не строка. Вы не можете использовать 'replace' на нем. Если вы хотите изменить содержимое ячейки, вы должны использовать * two * loop: один для строк и один для ячеек в строке. –

+0

@mmarboeuf: 'line [8]' - единственная ячейка/поле с символами '{' и '}' в ней, поэтому вы также можете сделать что-то вроде строки [8] .replace (...) ' а не перебирать каждый из них. – martineau

0

Вы можете использовать следующую инструкцию, чтобы удалить «{» и «}» в списке строки

line = ".".join(line).replace("{","").replace("}","").split(",") 
+0

Зачем разбирать файл как CSV, когда вы снова объединяете все ячейки? –

Смежные вопросы