[英]how do I extract data from links inside a webpage and then add them to already exists csv file?
[英]How do I quickly extract data from this massive csv file?
我有來自16個核的基因組數據。 第一列代表細胞核,后兩列分別代表支架(基因組部分)和在支架上的位置,最后兩列分別代表核苷酸和覆蓋率。 在不同的核中可以有相等的支架和位置。
使用開始和結束位置(每個支架的位置)的輸入,我應該輸出一個csv文件,該文件顯示從開始到結束范圍內每個核的數據(核苷酸和覆蓋率)。 我當時想通過有16列(每個原子核一個),然后從上到下顯示數據來做到這一點。 最左側的區域是該范圍內的參考基因組,我通過為其每個支架創建字典來訪問該基因組。
在我的代碼中,我有一個默認列表列表,因此鍵是一個將腳手架和位置組合在一起的字符串,而數據是一個列表數組,因此對於每個核,數據都可以附加到同一位置,最后,每個位置都有來自每個原子核的數據。
當然,這非常慢。 我應該怎么做呢?
碼:
#let's plan this
#input is start and finish - when you hit first, add it and keep going until you hit next or larger
#dictionary of arrays
#loop through everything, output data for each nucleus
import csv
from collections import defaultdict
inrange = 0
start = 'scaffold_41,51335'
end = 'scaffold_41|51457'
locations = defaultdict(list)
count = 0
genome = defaultdict(lambda : defaultdict(dict))
scaffold = ''
for line in open('Allpaths_SL1_corrected.fasta','r'):
if line[0]=='>':
scaffold = line[1:].rstrip()
else:
genome[scaffold] = line.rstrip()
print('Genome dictionary done.')
with open('automated.csv','rt') as read:
for line in csv.reader(read,delimiter=','):
if line[1] + ',' + line[2] == start:
inrange = 1
if inrange == 1:
locations[line[1] + ',' + line[2]].append([line[3],line[4]])
if line[1] + ',' + line[2] == end:
inrange = 0
count += 1
if count%1000000 == 0:
print('Checkpoint '+str(count)+'!')
with open('region.csv','w') as fp:
wr = csv.writer(fp,delimiter=',',lineterminator='\n')
for key in locations:
nuclei = []
for i in range(0,16):
try:
nuclei.append(locations[key][i])
except IndexError:
nuclei.append(['',''])
wr.writerow([genome[key[0:key.index(',')][int(key[key.index(',')+1:])-1],key,nuclei])
print('Done!')
文件: https : //drive.google.com/file/d/0Bz7WGValdVR-bTdOcmdfRXpUYUE/view ? usp = sharing https://drive.google.com/file/d/0Bz7WGValdVR-aFdVVUtTbnI2WHM/view?usp=sharing
(僅關注代碼中間的CSV部分)
您提供的示例csv文件超過2GB和77,822,354行。 在這些行中,您似乎只專注於26,804,253行或大約1/3。
作為一般建議,您可以通過以下方法加快處理速度:
numpy
, pandas
和pypy
您的數據是面向塊的,因此您可以使用FlipFlop
類型的對象來檢測您是否處於塊中。
csv的第一列是數字,因此您可以使用速度更快的Python in
運算符查找塊的開始和結尾,而不是將線分開並重新組裝兩列:
start = ',scaffold_41,51335,'
end = ',scaffold_41,51457,'
class FlipFlop:
def __init__(self, start_pattern, end_pattern):
self.patterns = start_pattern, end_pattern
self.state = False
def __call__(self, st):
rtr=True if self.state else False
if self.patterns[self.state] in st:
self.state = not self.state
return self.state or rtr
lines_in_block=0
with open('automated.csv') as f:
ff=FlipFlop(start, end)
for lc, line in enumerate(f):
if ff(line):
lines_in_block+=1
print lines_in_block, lc
打印:
26804256 77822354
在PyPy中運行大約9秒鍾,而在Python 2.7中運行大約46秒。
然后,您可以將讀取源csv文件的部分轉換為生成器,因此一次只需要處理一個數據塊。
(由於我花了很多時間試圖全面了解您的文件,因此肯定不正確。):
def csv_bloc(fn, start_pat, end_pat):
from itertools import ifilter
with open(fn) as csv_f:
ff=FlipFlop(start_pat, end_pat)
for block in ifilter(ff, csv_f):
yield block
或者,如果您需要將所有塊組合成一個字典:
def csv_line(fn, start, end):
with open(fn) as csv_in:
ff=FlipFlop(start, end)
for line in csv_in:
if ff(line):
yield line.rstrip().split(",")
di={}
for row in csv_line('/tmp/automated.csv', start, end):
di.setdefault((row[2],row[3]), []).append([row[3],row[4]])
在我的(老式)Mac上,在PyPy中執行該操作大約需要1分鍾,而在cPython 2.7中大約需要3分鍾執行。
最好
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.