2015-10-02 81 views
-1

我已兩個數據集格式如下:有效地發現在多千兆字節的數據集的行

infile1:

1  742429 SNP_A-1909444 T  C  .  .  PR  GT  0/0  0/0  0/0  
1  767376 SNP_A-2237149 G  A  .  .  PR  GT  0/0  0/0  0/0 
1  769185 SNP_A-4303947 A  G  .  .  PR  GT  0/0  ./.  0/0 

infile2:

1 742428 742430 rs3094315 SNP_A-1909444 C T + 
1 769184 769186 rs4040617 SNP_A-4303947 A G - 

如果從inifle1在第3列的數據和來自infile 2的列5中的數據同意,並且在infile2 ==「 - 」中的最後一列,那麼我想將來自infile1的列2,4,5中的值切換到來自infile2的列2,6,7中的值。

我可以做一些if語句,但是文件很大(幾個演出),所以它是絕對不可行的,因此,什麼是最好的方式在Python中執行它?

編輯:

for line in infile1: 
    line = line.split() 
    for row in infile2: 
     row = row.split() 
     if line[4] == row[6]: 
      if row[-1] == "-": 
       line[3] == row[3] 
       line[5] == row[7] 
       line[6] == row[8] 

我可以讀取一個文件的元組的列表,但不加快速度,因爲它是從開始每次迭代的時間要到文件的末尾。

+1

這個問題與Python的文件管理有關。這是重要的算法。請在python中顯示您的想法和嘗試 – Pynchia

+2

您應該使用實際的數據庫而不是兩個平面文本文件。沒有索引的平面文件存在限制,你會看到一個巨大的問題。模塊sqlite3內置於Python,非常強大,特別是作爲平面文件的替代品。 – msw

+1

您的代碼不僅掃描整個列表,而且還重新讀取file2作爲file1的_each_行。讀取一次file2並將其保存在內存中。 – alexis

回答

1

要在python中做到這一點,你需要通過SNP編號索引file2的行;你可以用字典來做到這一點:

rows2 = [ line.split() for line in infile2 ] 
data2 = dict((row[4], row) for row in rows2) 

for line in infile1: 
    r = line.split() 
    row2 = data2.get(r[2]) 
    if row2 and row2[-1] == "-": 
     <make the replacement> 

這假設當然文件2中的SNP ID是唯一的。

但是,如果這些文件真的太大而無法保存在內存中,或者如果您有很多這樣做的話,正確的方法是將它們作爲兩個數據庫表存儲。您所描述的轉換可以使用單個SQL查詢來執行。從python中,你可以簡單地將它們寫入sqlite3數據庫 - 無需安裝外部服務器或軟件。

0

首先,你最好指定一個更好的數據格式。從示例數據看來,數據是固定寬度列,但是您的代碼使用split(),這意味着可以將其視爲空格分隔的「CSV」(如果您的數據在每個單元中確實沒有空格) 。

然後,您最好將數據轉換爲數據庫。數據庫包含特製的算法處理您想要的內容,這是一種連接和選擇方法,其次是更新操作。數據庫優化適用,例如由SNP列索引,這可能會加快連接。

但是,如果您不想轉換數據,或者如果您想要在應用時進行轉換,則可以選中其他一些選項。我看第一個是Blaze ecosystemBlaze library本身可能會幫助您進行非核心處理(如果您的文件與您所說的一樣大,則需要該處理)。您還應該檢查Pandas類似數據庫的操作是否適用於您,例如join()和索引編制。在這種情況下,您可以嘗試像

dataset3 = dataset1.join(dataset2, "SNP") 
dataset3 = dataset3[dataset3.plus_minus_column=='-'] 
len1 = len(dataset1.columns)-1 # maybe -2? 
dataset1[3,5,6,dataset3.index] = dataset3[:,(3+len1,7+len1,8+len1)] 

後,你做了正確的索引。

您也可以嘗試使用update()

dataset1.update(dataset2[dataset2.plus_minus_column=='-',(2,6,7)]) 

當心,這些代碼片斷沒有經過測試(剛出來的內存),我真的不知道會不會給你任何的性能提升,如果他們工作的話。

相關問題