В настоящее время я пытаюсь читать данные из файлов .csv в Python 2.7 с количеством до 1 миллиона строк и 200 столбцов (файлы варьируются от 100 МБ до 1,6 ГБ). Я могу сделать это (очень медленно) для файлов с менее чем 300 000 строк, но как только я перейду выше, я получаю ошибки памяти. Мой код выглядит так:
def getdata(filename, criteria):
data=[]
for criterion in criteria:
data.append(getstuff(filename, criteron))
return data
def getstuff(filename, criterion):
import csv
data=[]
with open(filename, "rb") as csvfile:
datareader=csv.reader(csvfile)
for row in datareader:
if row[3]=="column header":
data.append(row)
elif len(data)<2 and row[3]!=criterion:
pass
elif row[3]==criterion:
data.append(row)
else:
return data
Причина для предложения else в функции getstuff заключается в том, что все элементы, которые соответствуют критерию, будут перечислены вместе в файле csv, поэтому я выхожу из цикла, когда прохожу мимо них, чтобы сэкономить время.
Мои вопросы:
Как мне заставить это работать с большими файлами?
Есть ли способ сделать это быстрее?
Мой компьютер имеет 8 ГБ ОЗУ, работает под управлением 64-битной Windows 7, а процессор - 3,40 ГГц (не уверен, какая информация вам нужна).
источник
Ответы:
Вы читаете все строки в список, а затем обрабатываете этот список. Не делай этого .
Обрабатывайте ряды по мере их создания. Если вам нужно сначала отфильтровать данные, используйте функцию генератора:
Я также упростил ваш тест фильтра; логика та же, но более лаконичная.
Поскольку вы сопоставляете только одну последовательность строк, соответствующую критерию, вы также можете использовать:
Теперь вы можете перейти
getstuff()
напрямую. Сделайте то же самое вgetdata()
:Теперь зацикливайтесь прямо
getdata()
в вашем коде:Теперь вы храните в памяти только одну строку вместо тысячи строк на критерий.
yield
делает функцию функцией- генератором , что означает, что она не будет работать, пока вы не начнете перебирать ее.источник
csv.DictReader
? Поскольку мои тесты с файлом .csv размером 2,5 ГБ показывают, что попытка перебора строки за строкой, подобная этой, при использовании этого, вместо того,csv.reader
чтобы вызывать процесс Python, увеличивающийся до полного использования памяти 2,5 ГБ.Хотя ответ Мартиджина, наверное, лучший. Вот более интуитивно понятный способ обработки больших файлов CSV для начинающих. Это позволяет обрабатывать группы строк или фрагментов одновременно.
источник
Я провожу изрядный анализ вибрации и смотрю на большие наборы данных (десятки и сотни миллионов точек). Мое тестирование показало, что функция pandas.read_csv () в 20 раз быстрее, чем numpy.genfromtxt (). А функция genfromtxt () в 3 раза быстрее, чем numpy.loadtxt (). Похоже, вам нужны панды для больших наборов данных.
Я разместил код и наборы данных, которые я использовал в этом тестировании, в блоге, в котором обсуждались MATLAB и Python для анализа вибрации .
источник
то, что сработало для меня, было и остается сверхбыстрым
Другое рабочее решение:
источник
df_train=df_train.compute()
строка в вашем первом решении не загружает весь набор данных в память ... чего он пытается не делать?Для тех, кто задает этот вопрос. Использование pandas с chunksize и usecols помогло мне прочитать огромный zip-файл быстрее, чем другие предложенные варианты.
источник
вот еще одно решение для Python3:
вот
datareader
функция генератора.источник
Если вы используете панда и много оперативной памяти (достаточно , чтобы прочитать весь файл в память) попробуйте использовать
pd.read_csv
сlow_memory=False
, например:источник