我有一個巨大的文件(1.2GB)的特徵向量保存爲csv文件。 爲了通過這些界限,我創建了一個python類,它可以一次一個批次地從巨型文件中將行加載到內存中。python,尋找,告訴,閱讀。從巨型csv文件讀取行
爲了讓這個類知道在文件中準確讀取批量batch_size的完整行(可以說batch_size = 10,000),在第一次使用巨型文件時,這個類會遍歷整個文件一次,並註冊每行的偏移量,並將這些偏移量保存到幫助文件中,以便稍後它可以「file.seek(starting_offset); batch = file.read(num_bytes)」讀取下一批行。
首先,我實現了線偏移的報名以這種方式:
offset = 0;
line_offsets = [];
for line in self.fid:
line_offsets.append(offset);
offset += len(line);
和它的工作與可愛giant_file1。
但隨後我在這個類的幫助下處理了這些特性並創建了giant_file2(具有標準化的特性)。 接下來,當我想讀取批量的行格式giant_file2時,它失敗了,因爲它將讀取的批處理字符串不在正確的位置(例如,讀取類似「-00 \ n15.467e-04」,.. 。「而不是」15.467e-04,... \ n「)。
因此,我試圖改變線偏移計算部分:
offset = 0;
line_offsets = [];
while True:
line = self.fid.readline();
if (len(line) <= 0):
break;
line_offsets.append(offset);
offset = self.fid.tell();
代替線的累積長度,主要的變化是,偏移寄存器我從fid.tell的結果取()。
該版本與giant_file2配合良好,但與giant_file1失敗。
我進一步調查了它,發現函數seek(),tell()和read()彼此不一致。 例如:
fid = file('giant_file1.csv');
fid.readline();
>>>'0.089,169.039,10.375,-30.838,59.171,-50.867,13.968,1.599,-26.718,0.507,-8.967,-8.736,\n'
fid.tell();
>>>67L
fid.readline();
>>>'15.375,91.43,15.754,-147.691,54.234,54.478,-0.435,32.364,4.64,29.479,4.835,-16.697,\n'
fid.seek(67);
fid.tell();
>>>67L
fid.readline();
>>>'507,-8.967,-8.736,\n'
有一些矛盾在這裏:當我(按fid.tell())在67字節定位一次讀取的行是一回事,並在第二次(FID再次當.tell()報告我位於字節67)讀取的行是不同的。
我不能相信tell()和seek()將我放到想要的位置,從所需行的開頭讀取。 在另一方面,當我使用(與giant_file1)字符串的長度作爲參考的尋求()我得到正確的位置:
fid.seek(0);
line = fid.readline();
fid.tell();
>>>87L
len(line);
>>>86
fid.seek(86);
fid.readline();
>>>'15.375,91.43,15.754,-147.691,54.234,54.478,-0.435,32.364,4.64,29.479,4.835,-16.697,\n'
這是怎麼回事呢?
我能想到的giant_file1和giant_file2之間的唯一區別是,在giant_file1中,值是用小數點(例如-0.435)寫的,在giant_file2中它們都是科學格式(例如-4.350e-01) 。我不認爲他們中的任何一個都是用unicode編碼的(我認爲是這樣,因爲我用簡單的file.read()讀取的字符串似乎可讀,我怎麼確定?)。
我非常感謝您的幫助,解釋,理由和可能的解決方案(或解決方法)。
謝謝, Yonatan。
是否有理由不能在處理文件時迭代文件行 –
除此之外,爲什麼不使用[csv'模塊](http://docs.python.org/library/csv .html),它允許你逐行處理? –
我同意@Jakob Bowyer,在計算偏移量時,你反覆遍歷整個文件中的所有行。那麼,爲什麼不處理呢? – Dhara