Таблицы#

Часто данные удобно представлять в виде таблиц. В экосистеме python существует множество инструментов для работы с табличными данными. Самый распространенный из них — библиотека pandas, основное внимание которой и будет уделено в этом курсе. На этой же страничке будет приведен краткий обзор других основных инструментов для работы с табличными данными.

Модуль стандартной библиотеки csv#

CSV (Comma-Separated Values) — самый простой и один из самых распространенных форматов хранения табличных данных. В CSV данные хранятся в текстовом формате, строке таблицы соответствует строка в файле CSV (иными словами разделитель строк — символ переноса строки), а значения внутри строки разделяются друг от друга специальным символом, в качестве которого обычно выступает символ запятой “,” (откуда и название).

Название,Количество спутников,Масса,Группа,Кольца
Меркурий,0,0.0055,земная группа,Нет
Венера,0,0.815,земная группа,Нет
Земля,1,1.0,земная группа,Нет
Марс,2,0.107,земная группа,Нет
Юпитер,62,317.8,газовый гигант,Да 
Сатурн,34,95.2,газовый гигант,Да
Уран,27,14.37,ледяной гигант,Да
Нептун,13,17.15,ледяной гигант,Да

Модуль стандартной библиотеки csv позволяет считывать табличные данные из файла в формате CSV. Про возможности этого модуля полезно знать, но на практике вы гораздо чаще будете пользоваться продвинутыми библиотеками для работы с таблицами, поэтому здесь ограничимся лишь примером, в котором содержимое таблицы считывается в список списков.

import os
import csv
from tabulate import tabulate

path = os.path.join("..", "..", "assets", "data", "tables", "planets.csv")

table = []
with open(path, encoding="utf-8") as csvfile:
    for row in csv.reader(csvfile, delimiter=","):
        table.append(row)

print(tabulate(table, headers="firstrow", tablefmt="grid"))
+------------+------------------------+----------+----------------+----------+
| Название   |   Количество спутников |    Масса | Группа         | Кольца   |
+============+========================+==========+================+==========+
| Меркурий   |                      0 |   0.0055 | земная группа  | Нет      |
+------------+------------------------+----------+----------------+----------+
| Венера     |                      0 |   0.815  | земная группа  | Нет      |
+------------+------------------------+----------+----------------+----------+
| Земля      |                      1 |   1      | земная группа  | Нет      |
+------------+------------------------+----------+----------------+----------+
| Марс       |                      2 |   0.107  | земная группа  | Нет      |
+------------+------------------------+----------+----------------+----------+
| Юпитер     |                     62 | 317.8    | газовый гигант | Да       |
+------------+------------------------+----------+----------------+----------+
| Сатурн     |                     34 |  95.2    | газовый гигант | Да       |
+------------+------------------------+----------+----------------+----------+
| Уран       |                     27 |  14.37   | ледяной гигант | Да       |
+------------+------------------------+----------+----------------+----------+
| Нептун     |                     13 |  17.15   | ледяной гигант | Да       |
+------------+------------------------+----------+----------------+----------+

Tip

В этом примере для вывода таблицы в красивом виде используются средства библиотеки tabulate.

Ограничения pandas и альтернативы#

Библиотека pandas — с большим запасом самая распространенная библиотека для работы с таблицами в python. Именно эта библиотека считается стандартом индустрии и многие другие инструменты (такие, как библиотеки по анализу данных и машинному обучению) хорошо дружат с этой библиотекой. Именно поэтому в рамках этого курса этой библиотеке и будет уделено основное внимание. Ниже приводится исходный код, необходимый для чтения того же самого CSV файла.

import pandas as pd

df = pd.read_csv(path)
df
Название Количество спутников Масса Группа Кольца
0 Меркурий 0 0.0055 земная группа Нет
1 Венера 0 0.8150 земная группа Нет
2 Земля 1 1.0000 земная группа Нет
3 Марс 2 0.1070 земная группа Нет
4 Юпитер 62 317.8000 газовый гигант Да
5 Сатурн 34 95.2000 газовый гигант Да
6 Уран 27 14.3700 ледяной гигант Да
7 Нептун 13 17.1500 ледяной гигант Да

Тем не менее важно понимать, что наряду с большим количеством преимуществ у pandas есть и ряд недостатков, которые ограничивают сферу его применений. Поэтому важно знать, что есть ряд альтернативных инструментов. У pandas есть три основных недостатка:

  • pandas всегда загружает таблицу целиком, т.е. можно работать только с помещающимися в оперативную память таблицами;

  • pandas не умеет производить вычисления лениво, что иногда приводит к не оптимальной производительности и чрезмерному потреблению ресурсов компьютера;

  • pandas навязывает наличие индекса у таблицы, что приводит к неоправданно усложненному коду в задачах, где такой индекс не возникает естественным образом.

Polars#

Все три вышеперечисленных недостатка не свойственны библиотеке Polars, которая довольно стремительно набирает популярность в сообществе разработчиков python из-за более продуманной архитектуры.

Ниже приводится пример, который демонстрирует, что считать CSV файл средствами этой библиотеки также легко, как и средствами pandas.

import polars as pl

df = pl.read_csv(path)
df
shape: (8, 5)
Название Количество спутников Масса Группа Кольца
str i64 f64 str str
"Меркурий" 0 0.0055 "земная группа" "Нет"
"Венера" 0 0.815 "земная группа" "Нет"
"Земля" 1 1.0 "земная группа" "Нет"
"Марс" 2 0.107 "земная группа" "Нет"
"Юпитер" 62 317.8 "газовый гигант... "Да "
"Сатурн" 34 95.2 "газовый гигант... "Да"
"Уран" 27 14.37 "ледяной гигант... "Да"
"Нептун" 13 17.15 "ледяной гигант... "Да"

Polars может не только загружать всю таблицу в оперативную память как pandas, но и сканировать её в ленивом режиме (или даже открывать в таком режиме таблицу, разбитую на несколько файлов), а затем при необходимости пробегаться по строкам этой таблицы и эффективно производить вычисления.

Кроме этого Polars может производить вычисления в ленивом режиме, т.е. пользователь библиотеки как бы делает запрос того, что он хочет, а результат он получит только тогда, когда результат этого запроса будет необходим. За счет такой организации вычислений библиотеке Polars удаётся в ряде ситуаций оптимизировать запрос, а также спланировать эти вычисления таким образом, чтобы максимально эффективно задействовать ресурсы компьютера (в том числе и многопоточность).

Dask и PySpark#

Однако и pandas и Polars ограничены одним компьютером, т.е. не позволяют производить распределенные вычисления на кластерах, что может оказаться критичным в случае реально больших данных. В таких ситуациях есть две основные опции: Dask и PySpark.

Dask является в каком-то смысле расширением для pandas. Из-за этого с ним гораздо проще освоиться, если уже знакомы с pandas. PySpark — обертка библиотеки Spark для Java, из-за чего её интерфейс существенно отличается от интерфейса pandas, но в PySpark встроен SQL движок, что позволяет довольно быстро освоиться с библиотекой, при условии знакомства с языком запросов SQL. Обе библиотеки могут производить вычисления лениво и на распределенных системах. В бизнес среде чаще предпочитают PySpark в связи с тем, что можно оплатить коммерческую лицензию и обеспечить себе техническую поддержку разработчиков библиотеки, чего нельзя сказать про Dask, т.к. она является проектом с открытым исходным кодом.