Вопрос или проблема
У меня есть большой файл (6 ГБ, около 17 миллионов строк) с 5 столбцами. Я хочу использовать первый столбец в качестве ключа и извлечь остальные 4 столбца. Я хочу задать несколько ключей. Мой код выглядит так:
import pandas as pd
df = pd.read_csv('large_file.gz',
chunksize=1000000)
key = "find_this" # элемент из столбца 1
for data in df:
if key in data['col1'].tolist():
found = data[data['col1'] == key]
break
print(found)
Как я могу оптимизировать скорость работы также для нескольких элементов?
ИЗМЕНЕНИЕ:
Я в основном хочу создать сокращённую локальную базу данных dbSNP, где я могу запрашивать геномное местоположение (хромосома, позиция, референтный, альтернативный) с использованием rsID.
Для этого я скачал этот VCF (16 ГБ) и предварительно обработал его с помощью awk
gzcat 00-All.vcf.gz | grep -v ## | awk '{print $3, $1, $2, $4, $4}' | gzip > 00-All_relevant.vcf.gz
Из этого файла я хочу запрашивать #CHROM, POS, REF и ALT с использованием столбца ID.
Если я правильно понимаю вашу проблему, вы можете читать и возвращать одну строку из вашего набора данных за раз с помощью следующего кода:
def stream_rows(path, max_len):
with gzip.open(path, 'rt', encoding='utf-8') as file:
next(file) # Пропустить заголовок
for line in file:
first_col = line[:max_len] # Извлечь первый столбец до max_len символов
yield first_col
def get_minibatch(row_stream, size, key): try: for _ in range(size): row = next(row_stream) if row == key: return True # Ключ найден except StopIteration: pass # Достигнут конец потока return False # Ключ не найден
Теперь вы можете читать строки CSV-файла, не загружая его полностью в ОЗУ. Вы можете использовать эти функции, как показано ниже:
row_stream=stream_rows(path, 20)
found=get_minibatch(row_stream,1000, key)
Ответ или решение
Для работы с большими файлами, превышающими доступную оперативную память, библиотека Pandas может использовать механизм «chunksize». Однако, если вы стремитесь к более эффективному поиску строк по нескольким ключам, есть альтернативные подходы, которые могут повысить производительность. Ниже я предложу решение, которое включает использование Pandas, а также более оптимизированный метод без загрузки всего файла в память.
Использование Pandas с Chunksize
Если вы все же хотите продолжать использовать библиотеку Pandas, модифицируйте ваш код следующим образом, чтобы ускорить процесс поиска для нескольких ключей:
import pandas as pd
# Загрузка файла частями
chunk_size = 1000000
keys = ["key1", "key2", "key3"] # Список ключей для поиска
found_rows = [] # Список для хранения найденных строк
for chunk in pd.read_csv('large_file.gz', chunksize=chunk_size):
# Фильтруем строки исходя из наличия ключей в первой колонке
filtered_chunk = chunk[chunk['col1'].isin(keys)]
# Добавляем найденные строки в наш список
found_rows.append(filtered_chunk)
# Объединяем все найденные строки в один DataFrame
result = pd.concat(found_rows, ignore_index=True)
print(result)
Использование Python-генераторов для обработки данных
Для большего контроля и уменьшения нагрузки на память можно использовать Python-генераторы для построчной обработки файла. Это подход более низкого уровня, который позволит вам не загружать всю таблицу целиком в память:
import gzip
def stream_rows(filepath):
with gzip.open(filepath, 'rt', encoding='utf-8') as f:
header = f.readline() # Пропустить заголовок
for line in f:
yield line.strip().split('\t') # Предполагаем, что разделитель - табуляция
def query_keys(filepath, keys):
keys_set = set(keys) # Преобразуем список ключей в множество для быстрого поиска
results = []
for row in stream_rows(filepath):
if row[0] in keys_set: # Проверяем, есть ли ключ в первой колонке
results.append(row) # Сохраняем строку, если ключ найден
return results
# Запустим поиск
found_rows = query_keys('00-All_relevant.vcf.gz', ["rsID1", "rsID2"])
for row in found_rows:
print(row)
Заключение
Выбор метода зависит от ваших требований к памяти и производительности. Используя Pandas с частичной загрузкой или обращаясь к правилам генерации, вы сможете интегрировать несколько ключей в ваш поиск и обрабатывать большие объемы данных более эффективно. Если файл очень большой, рекомендуется использовать генераторы, которые значительно экономят объем оперативной памяти.