Как я могу отфильтровать, какие строки CSV должны быть загружены в память с помощью pandas? Похоже, это вариант, который стоит найти read_csv
. Я что-то упускаю?
Пример: у нас есть CSV со столбцом с меткой времени, и мы хотим загрузить только те строки, метка времени которых больше заданной константы.
chunk['filed']>constant
я могу сэндвич его между 2 постоянными значениями? Например: constant1> chunk ['field']> constant2. Или я могу использовать «в диапазоне»?chunk[(chunk['field'] > constant2)&(chunk['field']<constant1)]
.loc
?chunk.loc[chunk['field'] > constant]
.loc
. Я не думаю, что.loc
существовал еще в 2012 году, но думаю, что в наши дни использование.loc
более явное.Я не нашел прямого способа сделать это в контексте
read_csv
. Однакоread_csv
возвращает DataFrame, который можно отфильтровать, выбирая строки по логическому векторуdf[bool_vec]
:filtered = df[(df['timestamp'] > targettime)]
Это выбор всех строк в df (при условии, что df - это любой DataFrame, такой как результат
read_csv
вызова, который хотя бы содержит столбец datetimetimestamp
), для которых значения вtimestamp
столбце больше, чем значение targettime. Аналогичный вопрос .источник
Если отфильтрованный диапазон является непрерывным (как это обычно бывает с фильтрами времени (меток)), то самым быстрым решением является жесткое кодирование диапазона строк. Просто комбинируйте
skiprows=range(1, start_row)
сnrows=end_row
параметрами. Тогда импорт займет секунды, тогда как принятое решение займет минуты. Несколько экспериментов с исходнымstart_row
кодом не являются огромными затратами, учитывая экономию времени на импорт. Обратите внимание, что мы сохранили строку заголовка, используяrange(1,..)
.источник
Альтернативой принятому ответу является применение read_csv () к StringIO, полученному путем фильтрации входного файла.
with open(<file>) as f: text = "\n".join([line for line in f if <condition>]) df = pd.read_csv(StringIO(text))
Это решение часто быстрее, чем принятый ответ, когда условие фильтрации сохраняет только небольшую часть строк.
источник
Если вы используете Linux, вы можете использовать grep.
# to import either on Python2 or Python3 import pandas as pd from time import time # not needed just for timing try: from StringIO import StringIO except ImportError: from io import StringIO def zgrep_data(f, string): '''grep multiple items f is filepath, string is what you are filtering for''' grep = 'grep' # change to zgrep for gzipped files print('{} for {} from {}'.format(grep,string,f)) start_time = time() if string == '': out = subprocess.check_output([grep, string, f]) grep_data = StringIO(out) data = pd.read_csv(grep_data, sep=',', header=0) else: # read only the first row to get the columns. May need to change depending on # how the data is stored columns = pd.read_csv(f, sep=',', nrows=1, header=None).values.tolist()[0] out = subprocess.check_output([grep, string, f]) grep_data = StringIO(out) data = pd.read_csv(grep_data, sep=',', names=columns, header=None) print('{} finished for {} - {} seconds'.format(grep,f,time()-start_time)) return data
источник
Вы можете указать
nrows
параметр.import pandas as pd df = pd.read_csv('file.csv', nrows=100)
Этот код хорошо работает в версии 0.20.3.
источник