2010-08-02 83 views
0

實施一些解決方案,在我previous question後,從文本文件中刪除的項目,我已經想出了以下解決方案:幫助使用python

reader = open('C://text.txt') 
writer = open('C://nona.txt', 'w') 
counter = 1  
names, nums = [], []  
row = reader.read().split(' ') 
x = len(row)/2 
for (a, b) in [(c, d) for c, d in zip(row[:x], row[x:]) if d!='na']: 
    print counter 
    counter +=1 
    names.append(a) 
    nums.append(b) 

writer.write(' '.join(names)) 
writer.write(' ') 
writer.write(' '.join(nums)) 

這個程序工作得很好較小的樣本數據集。但是,當我使用完整的數據集並導致python崩潰時,它會凍結。關於如何克服這一點的任何建議?

+1

請在Python崩潰時發佈stacktrace。它是否耗盡內存? – kobrien 2010-08-02 15:41:55

+0

你可以讓python把它分解成10-20個臨時文件,然後調用腳本來處理每個文件。如果您的計算機具有多個內核,那麼這也將執行「多線程」。 – 2010-08-02 15:42:22

+0

您是否考慮將數據轉換爲更標準的格式,如csv並從那裏使用它? – Wilduck 2010-08-02 15:43:39

回答

1

你應該做的是把你的文件分成兩個單獨的文件。你的邏輯應該做這樣的事情:

  1. 打開數據文件
  2. 打開文件名
  3. 下一個讀取數據
  4. 是它的名字?請參閱5.否則請參閱6
  5. 將名稱寫入名稱文件,請參閱3
  6. 是數字還是na?關閉名稱文件和打開號碼文件
  7. 讀取下一個數據
  8. 是數字還是na?看到7,否則寫入文件

,一旦你有你的文件分割成兩塊,你們可以一起對他們進行迭代:

names = open('names.txt') 
numbers = open('numbers.txt') 

for name, number in zip(names, numbers): 
    if not numbers == 'na': 
     output.write(name + " " + number) 

,或者你可以寫兩個不同的文件,然後將它們連接起來,如果這就是你需要的。

+0

既然看起來他的數據是一個龐大的名單,然後是一個龐大的數字列表,他甚至可以在一個好的文本編輯器中進行分解。值得注意的是,這種方法需要名稱和數字在單獨的行中包含每個名稱/數字。 – Wilduck 2010-08-02 15:54:02

+0

你能推薦一個好的文本編輯器嗎? – 2010-08-02 16:38:16

+0

他們中的任何一個? Notepad ++對於初學者來說是一個簡單的例子。我個人使用Vim(www.vim.org),它有一個非常陡峭的學習曲線,但一旦你把它記下來,它是非常有用的。 – 2010-08-02 17:48:05

0

您的文件以不幸的方式組織Pythonic處理。

請注意,當您撥打reader.read()時,您正在將整個文件讀入內存。假設這佔用了X個字節。

調用split將有效地添加另一個X字節的內存使用量,因爲它將爲該文件中的每個單獨字符串創建一個新字符串。

然後您可以撥打row[:x]row[x:],這將添加另一個X字節(因爲分片操作員進行復制)。

然後你調用zip,並創建一個列表理解等。字符串和元組是不可變的數據,這意味着你總是從頭開始創建它們。

我會在較低的水平上解決這個問題。打開一個文件描述符並將其指向文件的開頭。打開另一個,讓它尋找(na/0/1/2)值的開頭(你會知道這是通過計算空間的位置)。現在,一次只讀取一個名稱和一個值,如果該值不是「na」,則可以將該名稱寫入輸出文件。如果您還需要將值寫入輸出文件,請將它們保存在內存中,並在完成後立即寫入它們。

不幸的是,與僅使用Python提供的高級函數(您需要編寫可在字符級別運行的代碼)相比,這樣做更難以編寫代碼,但正如您所看到的,需要付出代價那些高級功能。