2015-10-07 2 views
0

Я сделал сценарий, который считывает заданный входной-файл (CSV), манипулирует данные каким-то образом и записывает выходной-файл (CSV).порядок изменения colums в формате CSV (питон)

В моем случае, данный вход-файл выглядит следующим образом:

| sku | article_name | 
| 1 | MyArticle | 

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

Мой выход-файл должен выглядеть следующим образом:

| article_name | another_column | sku | 
| MyArticle |    | 1 | 

Обратите внимание, что здесь появился новый столбец, который не находится в исходном csv- файл, но он должен быть напечатан YWAY (порядок важен, а)

Это то, что я до сих пор:

#!/usr/bin/env python 
# -*- coding: latin_1 -*- 

import csv 
import argparse 
import sys 


header_mappings = {'attr_artikel_bezeichnung1': 'ARTICLE LABEL', 
        'sku': 'ARTICLE NUMBER', 
        'Article label locale': 'Article label locale', 
        'attr_purchaseprice': 'EK-Preis', 
        'attr_salesPrice': 'EuroNettoPreis', 
        'attr_salesunit': 'Einheit', 
        'attr_salesvatcode': 'MwSt.-Satz', 
        'attr_suppliercode': 'Lieferantennummer', 
        'attr_suppliersitemcode': 'Artikelnummer Lieferant', 
        'attr_isbatchitem': 'SNWarenausgang'} 

row_mapping = {'Einheit': {'pc': 'St.'}, 
       'MwSt.-Satz': {'3': '19'}} 


def remap_header(header): 
    for h_map in header_mappings: 
     if h_map in header: 
      yield header_mappings.get(h_map), header.get(h_map) 


def map_header(header): 
    for elem in header: 
     yield elem, header.index(elem) 


def read_csv(filename): 
    with open(filename, 'rb') as incsv: 
     csv_reader = csv.reader(incsv, delimiter=';') 
     for r in csv_reader: 
      yield r 


def add_header(header, fields=()): 
    for f in fields: 
     header.append(f) 

    return header 


def duplicate(csv_row, header_name, fields): 
    csv_row[new_csv_header.index(fields)] = csv_row[new_csv_header.index(header_name)] 
    return csv_row 


def do_new_row(csv_row): 
    for header_name in new_csv_header: 
     for r_map in row_mapping: 
      row_content = csv_row[mapped_header.get(r_map)] 
      if row_content in row_mapping.get(r_map): 
       csv_row[mapped_header.get(r_map)] = row_mapping.get(r_map).get(row_content) 
     try: 
      yield csv_row[mapped_header.get(header_name)] 
     except TypeError: 
      continue 


if __name__ == '__main__': 

    parser = argparse.ArgumentParser() 
    parser.add_argument('-i', '--infile', metavar='CSV') 
    parser.add_argument('-o', '--outfile', metavar='CSV') 

    args = parser.parse_args() 
    arguments = vars(args) 
    if len(sys.argv[1:]) == 0: 
     parser.print_usage() 
     sys.exit(0) 

    # print arguments 
    # parse_csv(**arguments) 
    """ 
    """ 
    csv_reader_iter = read_csv(arguments.get('infile')) 

    # neuer csv header 
    new_csv_header = list() 
    csv_header = next(csv_reader_iter) 
    for h in csv_header: 
     if h in header_mappings: 
      new_csv_header.append(header_mappings.get(h)) 

    # print new_csv_header 
    new_csv_header = add_header(new_csv_header, ('Article label locale', 'Nummer')) 
    mapped_header = dict(remap_header(dict(map_header(csv_header)))) 
    # print mapped_header 

    with open(arguments.get('outfile'), 'wb') as outcsv: 
     csv_writer = csv.writer(outcsv, delimiter=';') 
     csv_writer.writerow(new_csv_header) 
     for row in csv_reader_iter: 
      row = list(do_new_row(row)) 
      delta = len(new_csv_header) - len(row) 
      if delta > 0: 
       row = row + (delta * ['']) 

      # duplicate(row, 'SNWarenausgang', 'SNWareneingang') 
      # duplicate(row, 'SNWarenausgang', 'SNWareneingang') 
      csv_writer.writerow(row) 


    print "Done." 
    """ 
    print new_csv_header 
    for row in csv_reader_iter: 
     row = list(do_new_row(row)) 
     delta = len(new_csv_header) - len(row) 
     if delta > 0: 
      row = row + (delta * ['']) 

     duplicate(row, 'Herstellernummer', 'Nummer') 
     duplicate(row, 'SNWarenausgang', 'SNWareneingang') 
     print row 
    """ 

Прямо сейчас, даже если он говорит, что «Статья LABEL» во-первых, SKU печатается первым. Мое предположение: Это из-за порядка csv-файла, так как sku - первое поле там ... правильно?

Спасибо заранее

ответ

0

Как riotburn уже предложил, вы можете использовать DictWriter и его fieldnames аргумент изменить порядок столбцов в новом файле.

Упорядочивание файл может выглядеть следующим образом:

def read_csv (filename): 
    with open(filename) as incsv: 
     reader = csv.DictReader(incsv, delimiter=';') 
     for r in reader: 
      yield r 

columns = ['article_name', 'another_column', 'sku'] 

with open('newfile.csv', 'w+') as f: 
    writer = csv.DictWriter(f, columns, delimiter=';') 
    writer.writeheader() 

    for row in read_csv('oldfile.csv'): 
     # add a property 
     row['another_column'] = 'foo' 

     # write row (using the order specified in columns) 
     writer.writerow(row) 
1

Если вы используете DictWritercsv из Lib Вы можете указать порядок столбцов. Используйте DictReader, чтобы читать строки из вашего файла в виде dicts. Затем вы просто указываете порядок ключей при создании своего DictWriter.

https://docs.python.org/2/library/csv.html#csv.DictReader

+0

бы я должен настроить «do_new_row» -функции? Извините, я просто привык к PHP = ( – DasSaffe

+0

Можете ли вы, если возможно, показать мне пример моего кода? Где должен быть этот DictWriter? – DasSaffe

+0

Вы хотите заменить 'csv.reader'' csv.DictReader 'и' csv.writer' с 'csv.DictWriter'. В приведенной ссылке есть примеры использования этих параметров. Вам придется изменить код, потому что теперь вы будете работать с' dicts' вместо 'lists'. – postelrich

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