2013-06-04 117 views
1

我正在從CSV文件的特定值中創建制表符分隔文件。 CSV文件包含上個月所有訂單,我需要正確格式化才能導入當前使用的會計軟件。下面是數據從CSV文件中的示例:將CSV轉換爲TDV - 格式問題

Customer Order Number Item Line Number Quantity Product Description 

cust1  Order #1    1    40    desc1 
cust1  Order #2    1    101    desc2 
cust2  Order #3    1    3    desc3 
cust2  Order #3    2    8    desc3 
cust2  Order #3    3    8    desc3 
cust1  Order #4    1    75    desc4 

現在,每個系列的Order Number我需要創建TDV文件看起來像這樣的一個部分:(忽略括號,這些都只是以顯示數值來自上面)

1  cust1   HA5ZV1   Desc1   Due Date  ... 
2  1 (Item #)  40 (Qty)  ...    ...    ... 

1  cust1   HA6A17   Desc2   Due Date  ... 
2  1 (Item #)  101 (Qty)  ...    ...    ... 

1  cust2   HA6AM1   Desc3   Due Date  ... 
2  1 (Item #)  3 (Qty)   ...    ...    ... 
2  2 (Item #)  8 (Qty)   ...    ...    ... 
2  3 (Item #)  8 (Qty)   ...    ...    ... 

希望這是有道理的。到目前爲止,我所做的是從原始CSV文件中創建一個字典,但對如何遍歷我的字典並將標題(標有「1」的行)寫入一次感到困惑,然後將值寫入(標有「2」的行)每次出現相同的Order Number。這是我到目前爲止的代碼:

data = csv.reader(open(import_dir)) 
fields = data.next() 
new_file = export_dir+os.path.basename(import_dir) 
tab_file = open(export_dir+os.path.basename(import_dir), 'a+') 
for row in data: 
    items = zip(fields, row) 
    item = {} 
    for (name, value) in items: 
     item[name] = value.strip() 
    tab_file.write('1\t'+item['Customer']+'\t'+item['Order Number']+'\t' 
        +item['Product Description']+'\t'+item['Due Date']+'\n'+ 
        '2\t'+item['Item Line Number']+'\t'+item['Quantity']+'\t'+ 
        ... 

但這種代碼把標題數據每行一個項目之前,而不是將其僅在每個訂單的開始。如果每個客戶只訂購一件商品,那就沒有問題,但由於某些訂單有多個訂單項,因此會導致格式化。如果任何人都能指出我會朝着正確的方向發展,那將是很棒的。謝謝!

+0

使用'csv.writer(tab_file,delimiter ='\ t')'它會寫入TSV文件.. –

回答

0

您希望使用客戶數itertools.groupby() tool,以便將輸入線:

import csv 
import os 
from itertools import groupby 
from operator import itemgetter 

new_file = os.path.join(export_dir, os.path.basename(import_dir)) 

with open(import_dir) as import, open(new_file, 'ab') as tab_file: 
    data = csv.reader(import) 
    writer = csv.writer(tab_file, delimiter='\t') 

    fields = next(data) 
    for customer, rows in groupby(data, key=itemgetter(0)): 
     first_row = next(rows) 
     item = {f: v.strip() for f, v in zip(fields, first_row)} 
     writer.writerow([1, customer, item['Order Number'], item['Product Description'], item['Due Date']) 
     writer.writerow([2, item['Item Line Number'], item['Quantity'], ...]) 
     for i, row in enumerate(rows, 3): 
      item = {f: v.strip() for f, v in zip(fields, row)} 
      writer.writerow([i, item['Item Line Number'], item['Quantity'], ...]) 

groupby()返回key功能的當前結果,並有鍵值的所有行的迭代。一旦下一行不再有相同的密鑰,就會啓動一個新組。

其他的事情我改變:

  • 使用with有你打開的文件自動關閉,不管是什麼事情發生。
  • 使用os.path.join()構建路徑
  • 使用csv.writer(..., delimiter='\t')來編寫製表符分隔的文件;它只是另一種CSV方言,真的。
  • 我用字典理解將你的行變成字典。另外,只需使用csv.DictReader()來做同樣的事情;不需要從第一行讀取字段。
+0

太棒了!謝謝!剛做了一些初步測試,看起來效果很好。 –

+0

感謝您幫助清理它。 –