Сортировка в pandas для больших наборов данных

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

data = data.sort(columns=["P_VALUE"], ascending=True, axis=0)

Есть ли быстрый способ сортировки моих данных по данному столбцу, который учитывает только куски и не требует загрузки целых наборов данных в память?

Ответы

Ответ 1

В прошлом я использовал пару penerable Linux sort и split, чтобы отсортировать массивные файлы, которые заглушили pandas.

Я не хочу унижать другой ответ на этой странице. Однако, поскольку ваши данные являются текстовыми форматами (как указано в комментариях), я думаю, что это огромная сложность, чтобы начать передачу его в другие форматы (HDF, SQL и т.д.), Для чего-то, что GNU/Linux-утилиты решали очень эффективно в течение последних 30-40 лет.


Скажите, что ваш файл называется stuff.csv и выглядит так:

4.9,3.0,1.4,0.6
4.8,2.8,1.3,1.2

Затем следующая команда будет сортировать его по третьему столбцу:

sort --parallel=8 -t . -nrk3 stuff.csv

Обратите внимание, что число потоков здесь равно 8.


Вышеупомянутое будет работать с файлами, которые вписываются в основную память. Когда ваш файл слишком велик, вы сначала разделите его на несколько частей. Так

split -l 100000 stuff.csv stuff

разделил бы файл на файлы длиной не более 100000 строк.

Теперь вы будете сортировать каждый файл отдельно, как указано выше. Наконец, вы бы использовали mergesort, снова через (waith for it...) sort:

sort -m sorted_stuff_* > final_sorted_stuff.csv

Наконец, если ваш файл не находится в CSV (скажем, это файл tgz), вы должны найти способ передать его версию CSV в split.

Ответ 2

Как я упоминал в комментариях, этот ответ уже предоставляет возможное решение. Он основан на формате HDF.

О проблеме сортировки есть, по крайней мере, три возможных способа решения этой проблемы.

Во-первых, вы можете попробовать напрямую использовать pandas, запрашивать HDF-хранимый-DataFrame.

Во-вторых, вы можете использовать PyTables, который pandas используется под капотом.

Francesc Alted дает подсказку в список рассылки PyTables:

Самый простой способ - установить для параметра sortby значение true в Table.copy(). Это вызывает операцию сортировки на диске, поэтому вы не нужно бояться вашей доступной памяти. Вам понадобится Pro для получения этой возможности.

В docs говорится:

sortby:    Если указано, и sortby соответствует столбцу с индексом, то копия будет отсортирована по этому индексу. Если вы хотите обеспечить полностью отсортированный порядок, индекс должен быть CSI. Обратную отсортированную копию можно достичь, указав отрицательное значение для ключевого слова step. Если sortby опущен или None, используется исходный порядок таблиц

В-третьих, еще с PyTables вы можете использовать метод Table.itersorted().

Из docs:

Таблица itersorted (sortby, checkCSI = False, start = None, stop = None, step = None)

Итерировать данные таблицы, следуя порядку индекса столбца sortby. Столбец sortby должен иметь полный индекс.


Другой подход заключается в использовании базы данных между ними. Подробный рабочий процесс можно увидеть в этом IPython Notebook, опубликованном в plot.ly.

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

Введение

Этот ноутбук исследует CSV файл 3.9Gb.

Этот ноутбук представляет собой праймер для анализа данных вне памяти с помощью

  • pandas: Библиотека с простыми в использовании структурами данных и инструментами анализа данных. Кроме того, интерфейсы к базам данных с избыточной памятью, например SQLite.
  • Ноутбук IPython: Интерфейс для написания и совместного использования кода, текста и графиков питона.
  • SQLite: автономная база данных без сервера, которая легко настраивается и запрашивается из pandas.
  • Plotly: Платформа для публикации красивых, интерактивных графиков с Python в Интернете.

Требования

import pandas as pd
from sqlalchemy import create_engine # database connection 

Импорт CSV-данных в SQLite

  • Загрузите CSV, chunk-by-chunk, в DataFrame
  • Немного обработайте данные, разделите неинтересные столбцы
  • Добавить его в базу данных SQLite
disk_engine = create_engine('sqlite:///311_8M.db') # Initializes database with filename 311_8M.db in current directory

chunksize = 20000
index_start = 1

for df in pd.read_csv('311_100M.csv', chunksize=chunksize, iterator=True, encoding='utf-8'):

    # do stuff   

    df.index += index_start

    df.to_sql('data', disk_engine, if_exists='append')
    index_start = df.index[-1] + 1

Значение запроса подсчитывает и упорядочивает результаты

Департамент жилищного строительства и развития получает большинство жалоб

df = pd.read_sql_query('SELECT Agency, COUNT(*) as `num_complaints`'
                       'FROM data '
                       'GROUP BY Agency '
                       'ORDER BY -num_complaints', disk_engine)

Ограничение количества отсортированных записей

Какая самая распространенная жалоба в каждом городе?

df = pd.read_sql_query('SELECT City, COUNT(*) as `num_complaints` '
                            'FROM data '
                            'GROUP BY `City` '
                   'ORDER BY -num_complaints '
                   'LIMIT 10 ', disk_engine)

Возможно связанные и полезные ссылки

Ответ 3

Blaze может быть инструментом для вас с возможностью работы с pandas и csv файлами из ядра. http://blaze.readthedocs.org/en/latest/ooc.html

import blaze
import pandas as pd
d = blaze.Data('my-large-file.csv')
d.P_VALUE.sort()  # Uses Chunked Pandas

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

Ответ 4

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

Предположим, что файл csv содержит два столбца, COL_1 и P_VALUE:

map.py:

import sys
for line in sys.stdin:
    col_1, p_value = line.split(',')
    print "%f,%s" % (p_value, col_1)

то следующая команда linux будет генерировать csv файл с сортировкой p_value:

cat input.csv | ./map.py | sort > output.csv

Если вы знакомы с hadoop, используя приведенный выше map.py, также добавляя простой файл reduce.py, вы создадите отсортированный файл csv через поточную систему hadoop.

Ответ 5

Вот мое честное предложение./Три варианта, которые вы можете сделать.

  • Мне нравится Pandas для его богатого документа и функций, но мне было предложено используйте NUMPY, поскольку он быстрее сравнивается с более крупными наборами данных. Вы можете думать об использовании других инструментов, а также для упрощения работы.

  • Если вы используете Python3, вы можете разбить свой большой фрагмент данных на группы и выполнить Congruent Threading. Я слишком ленив для этого, и это не выглядит круто, вы видите Panda, Numpy, Scipy строятся с перспективами проектирования оборудования, чтобы включить многопоточность.

  • Я предпочитаю это, это легкая и ленивая техника в соотв. мне. Проверьте документ http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.sort.html

Вы также можете использовать параметр "kind" в вашей функции pandas -sort.

Боже мой друг.