2012-01-25 4 views
9

Рассмотрим большой список именованных элементов (первая линия) вернулся из большого файла CSV (80 MB) с возможным прерванного шагомДоступ к списку элементов со списком индексов

name_line = ['a',,'b',,'c' .... ,,'cb','cc'] 

Я читал оставшуюся часть данные в строке за строкой, и мне нужно только обрабатывать данные с соответствующим именем. Данные могут быть похожими

data_line = ['10',,'.5',,'10289' .... ,,'16.7','0'] 

Я пробовал два пути. Один из них появляются пустые столбцы из каждой строки для чтения

blnk_cols = [1,3, ... ,97] 
while data: 
    ... 
    for index in blnk_cols: data_line.pop(index) 

другой компилирует элементы, связанные с именем из L1

good_cols = [0,2,4, ... ,98,99] 
while data: 
    ... 
    data_line = [data_line[index] for index in good_cols] 

в данных я использую, безусловно, будет больше пользы линии, тогда плохие линии, хотя это может достигать половины и половины.

Я использовал пакет cProfile и pstats, чтобы определить самые слабые ссылки в скорости, которые предполагали, что поп был самым медленным днем. Я переключился на список comp, и время почти удвоилось.

Я предполагаю, что одним быстрым способом было бы нарезать массив, извлекающий только хорошие данные, но это было бы сложно для файлов с чередующимися пробелами и хорошими данными.

то, что мне действительно нужно, чтобы быть в состоянии сделать

data_line = data_line[good_cols] 

эффективно передавая список индексов в списке, чтобы получить эти пункты. Прямо сейчас моя программа работает примерно 2,3 секунды для файла размером 10 МБ, а поп-аккаунты - около 0,3 секунды.

Есть ли более быстрый способ доступа к определенным местоположениям в списке. В C это просто будет де-ссылкой на массив указателей на правильные индексы в массиве.

Дополнения: name_line в файл перед чтением

a,b,c,d,e,f,g,,,,,h,i,j,k,,,,l,m,n, 

name_line после чтения и раскол ("")

['a','b','c','d','e','f','g','','','','','h','i','j','k','','','','l','m','n','\n'] 
+0

Что вы делаете с data_line? Вы просто повторяете это? Вы помещаете это в другую структуру данных? – Marcin

+0

Кроме того, вы пробовали генератор? – Marcin

+0

"Учитывается большой список, возвращенный из большого файла csv"? Вы читаете ** весь ** файл в один список? Зачем? Почему не обрабатывать каждую линию отдельно? –

ответ

8

Попробуйте выражение генератора,

data_line = (data_line[i] for i in good_cols) 

Также читайте здесь около Generator Expressions vs. List Comprehension

как главный ответ говорит вам: «В принципе, используйте выражение генератора, если все, что вы делаете, повторяется один раз».

Так что вам следует воспользоваться этим.

+0

Скорее это зависит от того, что вы делаете с ним. Преимущество генератора заключается в том, что он ленив, поэтому вы не выделяете много памяти для предметов, к которым вы обращаетесь только один раз. – Marcin

+0

@ Marcin. Да, пояснил мой ответ. –

+0

Обновлен весь мой код, чтобы соответствовать выражениям генератора. Я прохожу через каждую строку данных один раз для обработки (используя генератор с соответствующей индексацией вместо того, чтобы сначала вводить пустые значения). Код работает примерно на 3,3 секунды медленнее, потому что мне нужно воссоздать выражение генератора для каждой строки данных. –