2017-02-14 100 views
0

試圖讀取多個csv文件並將其解析爲txt文件。能夠讀取csv並將修改後的內容寫入txt文件。但是,在檢查具有原始csv的輸出時,發現第一條記錄不寫入文本文件。跳過2行的python csv閱讀器

樣品輸入csv文件的

INDEX,STRING1,STRING2,NUMBER1,NUMER2,DATE 
ABC,abc,bcd,123,321,01-FEB-2017 
BCD,bcd,cde,231,432,01-FEB-2017 

我的代碼:

file_list =[] 
list_of_files = os.listdir(os.getcwd()) 
for each_file in list_of_files: #reading csv files from the folder# 
    if (each_file.startswith('report') and each_file.endswith('.csv')): 
     file_list.append(each_file) 
     print(each_file) #all ok here# 

for f in file_list: #reading from list of files above# 
    with open (f, 'r') as fin: 
     reader=csv.reader(fin) 
     next(reader, None) 
     for row in csv.reader(fin): 
      #reading date and creating txt file for that date# 
      file_date=datetime.datetime.strptime(row[5],'%d-%b-%Y').strftime('%Y%m%d') 
      text_file = open("Report_for_"+file_date+".txt", "w") 
      #writing header for the output file# 
      text_file.write("<field0>,<date>,<field2>,<field3>,..."+"\n") 

      for row in csv.reader(fin): 
       if row[1] == 'abc' or row[1] == 'xyz': 
        ASCII=row[0]+','+file_date+','+row[2]+','+row[3]+','+row[4]+','+row[1] 
        text_file.write(ASCII +"\n") 
      print ("Processing for " +file_date) 
    text_file.close() 
print("done....") 

我以前next(reader, None)忽略標題。但是我的代碼也跳過了所有csv文件的第一條記錄。即使經過反覆的反覆試驗,也無法確定我出錯的地方。

+0

'如果行[1] == 'ABC' 或行[1] == 'xyz''可能成爲'如果行中的[1](' ABC」, 'XYZ')' – asongtoruin

回答

1

創建多個讀者:

reader=csv.reader(fin) 
next(reader, None) 
for row in csv.reader(fin): 
    # ... 
    for row in csv.reader(fin): 

讀者對象使用的緩衝,當你問一個行和緩衝不足時,更大的數據塊從文件中讀取對象。因此第一個reader()將數據拉入abuffer,然後當第二個csv.reader()開始讀取時,文件對象已被轉發到下一個塊。這同樣適用於您創建的第三個閱讀器。

遍歷reader,不csv.reader(fin)

reader=csv.reader(fin) 
next(reader, None) 
for row in reader: 
    # ... 
    for row in reader: 

我不明白爲什麼您使用兩個環路然而在這裏。如果您想分割寫出數據以根據日期分隔文件,請將打開的文件存儲在字典中,然後您可以從中選擇一個傳出文件。

你也想用一個csv.writer()對象寫出行到一個新的文件,而不是用手工拼接用逗號:

try: 
    open_writing_files = {} 
    writers = {} 

    for f in file_list: 
     with open (f, 'rb') as fin: 
      reader = csv.reader(fin) 
      next(reader, None) 

      for row in reader(fin): 
       if row[1] not in ('abc', 'xyz'): 
        # not interesting, continue to the next row 
        continue 

       file_date = datetime.datetime.strptime(row[5], '%d-%b-%Y').strftime('%Y%m%d') 
       writer = writers.get(file_date) 
       if writer is None: 
        # no writer for this date yet, create one 
        text_file = open("Report_for_{}.txt".format(file_date), "wb") 
        open_writing_files[file_date] = text_file 
        writer = writers[file_date] = csv.writer(text_file) 
        writer.writerow(['<field0>', '<date>', '<field2>', '<field3>']) 

       # construct a new row for the output file, consisting of 
       # indices 0, the date, indices 2, 3, 4 and 1. 
       writer.writerow([row[0], file_date] + row[2:5] + [row[1]]) 

finally: 
    for fileobj in open_writing_files.itervalues(): 
     fileobj.close() 

以上:

  1. 打開文件,對於一個給定每個節目只需要一次。
  2. 對於每個文件只使用一次csv.reader()csv.writer()
  3. 通過以二進制模式打開文件,使用CSV文件讀取和寫入的最佳做法。 csv模塊以這種方式正確處理換行處理。
  4. 確保所有寫入文件僅在所有CSV讀取完成時關閉。
  5. 提前測試感興趣的行;這樣,您將不會爲只在跳過的行中出現的日期打開額外的每日日期輸出文件。
+0

@martijin_pieters – user3017186

+0

謝謝@ martijn-pieters。這個代碼比我的嘗試更加優雅和精緻。 我在這裏有幾個問題。我想我一定是做錯了什麼,但無法弄清楚什麼。 我在''abc','xyz')中使用'if row [1]:' 它只過濾前1條記錄(帶過濾器),但不循環文件。我在這裏做錯了什麼。 我做的其他變化是: 替換爲'閱讀器中的行(fin):'with'爲閱讀器中的行:' – user3017186

+0

@ user3017186:hrm,似乎我在那裏放了一行重要的代碼;我添加了'繼續'。這跳過*只是一行*,而不是全部文件。 –