2016-08-01 5 views
2

У меня есть очень большой файл CSV, который содержит более 500 миллионов строк.Извлечение строк из чрезвычайно большого (48 ГБ) CSV-файла на основе условия

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

with open('/home/Documents/1681.csv', 'rb') as f: 
    reader = csv.DictReader(f) 
    rows = [row for row in reader if row['flag_central'] == 1] 

Здесь условие, что если flag_central == 1, мне нужна строка.

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

Есть ли в любом случае я могу извлечь эти определенные строки из файла CSV на основе вышеуказанного условия?

+0

использовать grep и фильтровать то, что вы хотите, и направить его на python и прочитать его как csv. – YOU

+0

@YOU: Не могли бы вы привести пример в качестве ответа? – ThePredator

+0

Его просто подсказка. – YOU

ответ

2

Если это одноразовая задача а, я предложил бы использовать Unix команду, а затем обработать экстракт:

cat file | awk -F , '{ if ($5 == "1") print $0 }' > extract.csv 

где -F указывает разделитель столбцов, а 5 - номер столбца. понять это первый по

cat file | head -n 1 | tr ',' '\n' | nl | grep flag_central 
=> 
5 flag_central 
^ this is the field number ($5) 

Таким образом, вы не понесете стоимость преобразования файла CSV в объекты питона первым. В зависимости от вашего варианта использования YMMV.

+0

Как выполнить вышеописанное для нескольких команд? т. е. если я хочу добавить другое условие – ThePredator

+0

, то общая форма оператора if будет 'if (выражение) action', где' expression' представляет собой любую комбинацию операций, которые дают либо true (отличное от нуля), либо false (ноль). Таким образом, вы можете комбинировать несколько условий с помощью булевых операторов, например. 'if ($ 5 ==" 1 "&& $ 1 ==" foo ") ...'. Для более сложных примеров посмотрите [здесь] (http://stackoverflow.com/search?q=awk+conditions). Обратите внимание, если условная логика выходит за рамки нескольких терминов, например. вложенные условия или даже синтаксический анализ, я бы рекомендовал сделать это как второй шаг на питоне, вместо написания сложного awk-скрипта. – miraculixx

3

Вы можете сделать это с помощью pandas:

import pandas as pd 

chunk_list=[] 
for chunk in pd.read_csv('/home/Documents/1681.csv', chunksize=10000): 
    chunk_list.append(chunk[chunk['flag_central'] == 1]` 

final_df = pd.concat(chunk_list) 

В основном это будет читать 10000 строк в то время, и фильтровать строки, которые не удовлетворяют Ваше условие, они получают добавляется в список и при полных ломтях конкатенируются в окончательный информационный кадр

+0

Я получаю сообщение об ошибке: 'TypeError: parser_f() получил неожиданный аргумент ключевого слова 'mode'' – ThePredator

+0

OK' 'режим не имеет значения, вы действительно можете удалить его – EdChum

+0

' final_df', какой тип массива это будет? – ThePredator

2

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

import pandas as pd 
tp = pd.read_csv('/home/Documents/1681.csv', iterator=True, chunksize=10000) 
df = pd.concat(tp, ignore_index=True) 

Оттуда вы бы тогда быть в состоянии извлечь строку, которую вы заинтересованы в с:

rows = df[df['flag-central'] == 1] 

Если вы хотели бы вернуть это в CSV-файл можно затем использовать to_csv:

rows.to_csv('filename.csv') 
1

Если это повторяющийся процесс и/или у вас есть более сложные условия для процесса, здесь подход быстро, низко-памяти в Python, который вы там быстро:

#!/usr/bin/env python 
# put this in parsecsv.py, then chmod +x parsecsv.py 
import sys 
output = lambda l: sys.stdout.write(l) 
for line in sys.stdin: 
    fields = line.split(',') 
    # add your conditions below 
    # call output(line) to output 
    if fields[0] == "foo": 
     output(line) 

Это предназначено для можно использовать в качестве фильтра трубопровода из командной строки:

$ cat file | parsecsv > extract.csv 

на самом деле я написал несколько более generic & maintainable template, что вы могли бы оказаться полезными.

 Смежные вопросы

  • Нет связанных вопросов^_^