簡體   English   中英

尋找一種更有效的方法來重組Python中的大量CSV

[英]Looking for a more efficient way to reorganize a massive CSV in Python

我一直在研究一個問題,我從大輸出.txt文件中獲取數據,現在必須以.csv的形式解析和重組某些值。

我已經編寫了一個腳本,根據它的數據類型(航班ID,緯度,經度等)將所有數據輸入到列中的.csv中,但它的順序不正確。 所有值都應根據相同的航班ID進行分組,從最早的時間戳到最新的時間戳。 幸運的是,我的.csv具有正確時間順序的所有值,但未根據航班ID進行適當組合。

要清除我的描述,它現在看起來像這樣,

(“時間x”只是為了說明):

20110117559515, , , , , , , , ,2446,6720,370,42  (Time 0)                               
20110117559572, , , , , , , , ,2390,6274,410,54  (Time 0)                               
20110117559574, , , , , , , , ,2391,6284,390,54  (Time 0)                               
20110117559587, , , , , , , , ,2385,6273,390,54  (Time 0)                               
20110117559588, , , , , , , , ,2816,6847,250,32  (Time 0) 
... 

它應該像這樣訂購:

20110117559515, , , , , , , , ,2446,6720,370,42  (Time 0)
20110117559515, , , , , , , , ,24xx,67xx,3xx,42  (Time 1)
20110117559515, , , , , , , , ,24xx,67xx,3xx,42  (Time 2)
20110117559515, , , , , , , , ,24xx,67xx,3xx,42  (Time 3)
20110117559515, , , , , , , , ,24xx,67xx,3xx,42  (Time N)
20110117559572, , , , , , , , ,2390,6274,410,54  (Time 0)
20110117559572, , , , , , , , ,23xx,62xx,4xx,54  (Time 1)
... and so on

.csv I輸出中有130萬行,以簡化操作。 我99%有信心我寫的下一個腳本中的邏輯來修復排序是正確的,但我擔心這是非常低效的。 我最后添加了一個進度條,看看它是否取得了進展,不幸的是這就是我所看到的:

在此輸入圖像描述

這是處理運算的代碼(如果你願意,可以跳到問題區域):

## a class I wrote to handle the huge .csv's ##
from BIGASSCSVParser import BIGASSCSVParser               
import collections                                                              


x = open('newtrajectory.csv')  #file to be reordered                                                  
linetlist = []                                                                  
tidict = {}               

'' To save braincells I stored all the required values
   of each line into a dictionary of tuples.
   Index: Tuple ''

for line in x:                                                                  
    y = line.replace(',',' ')                                                   
    y = y.split()                                                               
    tup = (y[0],y[1],y[2],y[3],y[4])                                            
    linetlist.append(tup)                                                       
for k,v in enumerate(linetlist):                                                
    tidict[k] = v                                                               
x.close()                                                                       


trj = BIGASSCSVParser('newtrajectory.csv')                                      
uniquelFIDs = []                                                                
z = trj.column(0)   # List of out of order Flight ID's                                                     
for i in z:         # like in the example above                                                           
    if i in uniquelFIDs:                                                        
        continue                                                                
    else:                                                                       
        uniquelFIDs.append(i)  # Create list of unique FID's to refer to later                                               

queue = []                                                                              
p = collections.OrderedDict()                                                   
for k,v in enumerate(trj.column(0)):                                            
    p[k] = v  

到目前為止一切都很好,但是在下一個部分,我的計算機要么窒息,要么我的代碼很糟糕:

for k in uniquelFIDs:                                                           
    list = [i for i, x in p.items() if x == k]                                  
    queue.extend(list)                                                          

我們的想法是,對於每個唯一值,按順序迭代130萬個值並按順序返回每個匹配項的索引,並將這些值附加到列表中。 之后,我只是要讀取大量索引列表,並將該行數據的內容寫入另一個.csv文件。 塔達! 可能非常低效。

這有什么不對? 有沒有更有效的方法來解決這個問題? 我的代碼有缺陷,還是我只是對我的筆記本電腦殘忍?

更新:

我發現,隨着我正在處理的數據量,它需要9-10個小時。 我有一半正確吐出4.5。 我可以暫時解決一夜之間的危機,但下次可能會使用數據庫或其他語言。 如果我知道我提前得到了什么,我會的,哈哈。

調整我的SSD的睡眠設置后,它只需要3個小時來處理。

您可以嘗試UNIX sort實用程序:

sort -n -s -t, -k1,1 infile.csv > outfile.csv

-t設置分隔符, -k設置排序鍵。 -s穩定排序, -n使用數字比較。

如果CSV文件適合你的RAM(例如小於2GB),那么你可以閱讀整個內容並對其進行sort

data = list(csv.reader(fn))
data.sort(key=lambda line:line[0])
csv.writer(outfn).writerows(data)

如果你不捶打,這不應該花費相當長的時間。 請注意, .sort是一種穩定的排序 ,因此當密鑰相等時,它將保留文件的時間順序。

如果它不適合RAM,你可能想要做一些有點聰明的事情。 例如,您可以存儲每行的文件偏移量,以及行中的必要信息(時間戳和航班ID),然后對這些信息進行排序,並使用行偏移信息寫入輸出文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM