2011-07-25 38 views
0

我有一堆文件名,我需要將它們放在一起並放到一個新文件中。第一列是日期。如果日期從一個文件重疊到另一個文件,我希望下一個要追加的文件替換已有的文件。例如,如果第一個文件是一樣的東西:使用Python替換某些行並在CSV文件中附加其餘行

1/5/2010 'hello' 
1/6/2010 'goodbye' 
1/7/2010 'yes' 

和第二個文件是:

1/7/2010 'No' 
1/8/2010 "spam' 
1/9/2010 'today' 

我想我的新文件看起來像這樣:

1/5/2010 'hello' 
1/6/2010 'goodbye' 
1/7/2010 'No' 
1/8/2010 'spam' 
1/9/2010 'today' 

眼下我正在嘗試這樣的事情,但沒有得到正確的結果。 (閱讀器2和讀取器分別是指第二個文件和所述第一文件,newfile2.csv已經有文件1的內容)

for row in reader2: 
    for row2 in reader: 
     if row == row2: 
      target = open('newfile2.csv', 'wb') 
      writer = csv.writer(target) 
      writer.writerow(row) 
      target.close() 
     else: 
      target = open('newfile2.csv', 'ab') 
      writer = csv.writer(target) 
      writer.writerow(row) 
      target.close() 

任何想法將不勝感激。謝謝 好吧,所以我想我應該在閱讀完一些評論後澄清一下。順序很重要。在這個代碼的最後,我希望每年的每一天的數據都是按順序排列的。好消息是數據已經在文件中有序,只有一些重複。

有一個以上的重複。例如,我實際處理的第一個文件一直持續到3月9日,而我希望它在2月底停止。我想從我的第二個文件中獲取所有3月份的數據。

此外,大約有1500多行,因爲在真實文件中,一天中的每個小時也是行的一部分。

我希望澄清我需要做的事情。

我覺得像我上面發佈的代碼,但只檢查每一行的第一列(因爲只有日期將是對方的重複)可能工作?現在我正在檢查整行,而日期是重複的,整個行是唯一的。

哦,是的最後一件事。我想要刪除所有重複項。

回答

1

嘗試:

dictio = {} 
for row in reader: 
    [date, text] = row.split() 
    dictio[date] = text 

for row in reader2: 
    [date, text] = row.split() 
    dictio[date] = text 

target = open('newfile2.csv', 'wb') 
writer = csv.writer(target) 
for date, text in dictio.iteritems(): 
    writer.writerow("%s %s" %(date, text)) 
target.close() 

編輯:評論後,如果您想保持項目的順序,改變

dictio = {} 

dictio = collections.OrderedDict() 

這個作品for python> 2.6

+0

這根本不保持行的順序。此外,它消除了所有重複項,而不僅僅是連接文件結尾的順序重複項。 – agf

+0

@agf,對。這個問題在你的問題中沒有明確說明......它們有多重疊?只有最後一行? – joaquin

+0

不是我的問題。只是說不清楚他做了什麼,特別是在訂購方面。 – agf

0

如果文件不是很大(成千上萬的行),這對任何數量的輸入文件都適用,維護行順序,並且只刪除指定的重複項。

input_files = 'a.csv, b.csv, c.csv, d.csv' 

last = '.' 
# open the outfile and make the csv writer here 
for input_file in input_files: 
    # open the infile and make the csv reader here 
    lines = reader.readlines() 
    # save the last line for later 
    last_new = reader.pop() 
    if last.split()[0] != lines[0].split()[0]: 
     writer.writeln(last) 
    writer.writelines(lines) 
    last = last_new 
    reader.close() 
writer.writeln(last) 
writer.close() 

如果你想擺脫所有重複的,使用dict方法在其他的答案之一,但不使用dict,({}),使用collections.OrderedDict()這樣的行留在順序。

OrderedDict for Python 2.4-2.6的替代方法是http://pypi.python.org/pypi/ordereddict

0

到目前爲止發佈的答案都依賴於將數據讀入內存,這對於小型輸入文件來說很好。但是既然你說你的輸入文件已經被排序,那麼就可以逐行處理輸入文件,這樣你就可以用任意數量的行來處理文件了。

假設你有csvreaders列表(按優先順序 - 如果許多文件包含使用相同的密鑰,從第1讀寫該行將採取的行),用於輸出一個CSV writer和功能key提取的排序鍵的每一行,你可以只輸出總是包含最小排序鍵值,並推動具有相同關鍵字值的所有讀者行:

def combine(readers, writer, key): 
    rows = [reader.next() for reader in readers] 
    while rows: 
     # select the first input row with the minimum sort key value 
     row = min(rows, key=key) 
     writer.writerow(row) 
     # advance all readers with the minimum sort key value 
     min_key = key(row) 
     for i in xrange(len(readers)): 
      if key(rows[i]) == min_key: 
       try: 
        rows[i] = readers[i].next() 
       except StopIteration: 
        # reader exhausted, remove it 
        del rows[i] 
        del readers[i] 

查看該示例文件可排序的關鍵,你必須解析日期,因爲它的格式有些尷尬。在文件中使用ISO %Y-%m-%d日期會使生活更輕鬆,因爲它們自然排序。

import datetime 

def key(row): 
    return datetime.datetime.strptime(row[0], '%m/%d/%Y') 

把它放在一起,所以你可以運行python combine.py input1.csv input2.csv > output.csv。輸入文件的順序是相反的,以便稍後指定的文件將覆蓋先前指定的文件。

import csv, sys 

delimiter = ' '       # used in the example input files 
readers = [csv.reader(open(filename), delimiter=delimiter) 
      for filename in reversed(sys.argv[1:])] 
writer = csv.writer(sys.stdout, delimiter=delimiter); 
combine(readers, writer, key) 
相關問題