Сравнение
В этом разделе пакет DataFrames.jl сравнивается с другими фреймворками манипулирования данными в Python, R и Stata.
Пример набора данных можно создать с помощью следующего кода:
using DataFrames
using Statistics
df = DataFrame(grp=repeat(1:2, 3), x=6:-1:1, y=4:9, z=[3:7; missing], id='a':'f')
df2 = DataFrame(grp=[1, 3], w=[10, 11])
|
Некоторые операции изменяют таблицы, поэтому предполагается, что каждая операция выполняется с исходным фреймом данных. |
Обратите внимание, что в представленных ниже сравнениях такие предикаты, как x -> x >= 1, могут быть записаны более кратко: =>(1). Дополнительным преимуществом такой формы является то, что она компилируется только один раз за сеанс Julia (в отличие от формы x -> x >= 1, которая каждый раз определяет новую анонимную функцию).
Сравнение с пакетом pandas в Python
В следующей таблице основные функции пакета DataFrames.jl сравниваются с пакетом Python pandas (версии 1.1.0):
import pandas as pd
import numpy as np
df = pd.DataFrame({'grp': [1, 2, 1, 2, 1, 2],
'x': range(6, 0, -1),
'y': range(4, 10),
'z': [3, 4, 5, 6, 7, None]},
index = list('abcdef'))
df2 = pd.DataFrame({'grp': [1, 3], 'w': [10, 11]})
Так как пакет pandas поддерживает множественное индексирование, в примере фрейма данных в качестве индексов строк используются индексы с a по f, а не отдельный столбец id.
Доступ к данным
| Операция | pandas | DataFrames.jl |
|---|---|---|
Индексирование ячеек по позиции |
|
|
Получение среза строк по позиции |
|
|
Получение среза столбцов по позиции |
|
|
Индексирование строк по метке |
|
|
Индексирование столбцов по метке |
|
|
Получение среза столбцов по метке |
|
|
|
|
|
Смешанное индексирование |
|
|
Обратите внимание, что в Julia применяется индексирование с отсчетом от 1 и включением обеих границ. Для обозначения последнего индекса можно использовать специальное ключевое слово end. Аналогичным образом, для обозначения последнего первого можно использовать ключевое слово begin.
Кроме того, при индексировании фрейма данных с помощью функции findfirst возвращается один объект DataFrameRow. Если id не является уникальным, вместо этого можно использовать функцию findall или логическое индексирование. В этом случае возвращается объект DataFrame, содержащий все соответствующие строки. Следующие две строки кода функционально эквивалентны:
df[findall(==('c'), df.id), :]
df[df.id .== 'c', :]
При индексировании в DataFrames.jl всегда возвращается согласованный и предсказуемый тип. В отличие от этого, функция loc в pandas возвращает объект Series, ели в индексе ровно одно значение 'c', или объект DataFrame, если есть несколько строк со значением индекса 'c'.
Основные операции
| Операция | pandas | DataFrames.jl |
|---|---|---|
Свертка нескольких значений |
|
|
|
|
|
|
|
|
Добавление новых столбцов |
|
|
Переименование столбцов |
|
|
Выборка и преобразование столбцов |
|
|
Сортировка строк |
|
|
|
|
|
Удаление отсутствующих строк |
|
|
Выбор уникальных строк |
|
|
Обратите внимание, что в pandas значения NaN в аналитических функциях по умолчанию пропускаются. В отличие от этого, функции Julia не пропускают значения NaN. При необходимости вы можете отфильтровать значения NaN перед обработкой, например, так: mean(Iterators.filter(!isnan, x)).
В pandas NaN служит для представления как отсутствующих данных, так и значения с плавающей запятой, не являющегося числом. Для представления отсутствующих данных в Julia определено специальное значение missing. В DataFrames.jl соблюдаются общие правила распространения значений missing, принятые по умолчанию в Julia. При необходимости с помощью функции skipmissing можно удалить отсутствующие данные. Дополнительные сведения см. в разделе Missing Data.
Кроме того, в pandas после применения функции сохраняется исходное имя столбца. В DataFrames.jl по умолчанию добавляется суффикс к имени столбца. Для простоты в приведенных выше примерах имена столбцов не согласованы между pandas и DataFrames.jl (чтобы сохранить прежние имена столбцов, в функции select, transform и combine можно передать именованный аргумент renamecols=false).
Изменяющие операции
| Операция | pandas | DataFrames.jl |
|---|---|---|
Добавление новых столбцов |
|
|
|
||
|
|
|
Переименование столбцов |
|
|
Сортировка строк |
|
|
Удаление отсутствующих строк |
|
|
Выбор уникальных строк |
|
|
В целом в DataFrames.jl соблюдается принятое в Julia соглашение, согласно которому в имени функции, предполагающей изменение данных, используется символ !.
Группирование и агрегирование данных
В DataFrames.jl есть функция groupby, позволяющая выполнять операции с каждой группой по отдельности. Результатом функции groupby является объект GroupedDataFrame, который можно обработать с помощью функции combine, transform или select. В таблице ниже показаны некоторые распространенные сценарии группирования и агрегирования.
| Операция | pandas | DataFrames.jl |
|---|---|---|
Агрегирование по группам |
|
|
Переименование столбца после агрегирования |
|
|
Добавление агрегированных данных в виде столбца |
|
|
…и выбор выходных столбцов |
|
|
Обратите внимание, что в pandas для одномерного результата возвращается объект Series, если только затем не вызывается reset_index. В соответствующих примерах для DataFrames.jl возвращается эквивалентный объект DataFrame. Рассмотрим первый пример:
>>> df.groupby('grp')['x'].mean()
grp
1 4
2 3
Name: x, dtype: int64
Для DataFrames.jl он будет выглядеть так:
julia> combine(groupby(df, :grp), :x => mean)
2×2 DataFrame
Row │ grp x_mean
│ Int64 Float64
─────┼────────────────
1 │ 1 4.0
2 │ 2 3.0
В DataFrames.jl объект GroupedDataFrame поддерживает эффективный поиск ключей. Поэтому частый поиск ключей выполняется с высокой производительностью.
Более сложные команды
В этом разделе представлены более сложные примеры.
| Операция | pandas | DataFrames.jl |
|---|---|---|
Комплексная функция |
|
|
Агрегирование нескольких столбцов |
|
|
|
|
|
|
|
|
Применение функции к нескольким переменным |
|
|
Построчная операция |
|
|
|
|
|
DataFrame в качестве входного объекта |
|
|
DataFrame в качестве выходного объекта |
|
|
Обратите внимание, что в pandas после операции groupby порядок строк сохраняется, в то время как в DataFrames.jl они группируются по предоставленным ключам после операции combine, но при выполнении операций select и transform сохраняется исходный порядок строк.
Объединение фреймов данных
DataFrames.jl поддерживает операции объединения наподобие тех, которые используются в реляционных базах данных.
| Операция | pandas | DataFrames.jl |
|---|---|---|
Внутреннее объединение |
|
|
Внешнее объединение |
|
|
Левое объединение |
|
|
Правое объединение |
|
|
Полуобъединение (фильтрация) |
|
|
Антиобъединение (фильтрация) |
|
|
При объединении нескольких столбцов как в pandas, так и в DataFrames.jl в качестве значения именованного аргумента on принимается массив.
В случае с полуобъединением и антиобъединением в pandas по-прежнему можно использовать функцию isin при условии, что ключи объединения объединены в кортеж. В DataFrames.jl она работает обычным образом с массивом ключей объединения, указанным в именованном аргументе on.
Сравнение с пакетом dplyr в R
В следующей таблице основные функции пакета DataFrames.jl сравниваются с пакетом R dplyr (версии 1):
df <- tibble(grp = rep(1:2, 3), x = 6:1, y = 4:9,
z = c(3:7, NA), id = letters[1:6])
| Операция | dplyr | DataFrames.jl |
|---|---|---|
Свертка нескольких значений |
|
|
Добавление новых столбцов |
|
|
Переименование столбцов |
|
|
Выборка столбцов |
|
|
Выборка и преобразование столбцов |
|
|
Выборка строк |
|
|
Сортировка строк |
|
|
Как и в dplyr, некоторые из этих функций могут применяться к сгруппированным фреймам данных; в этом случае они работают с отдельными группами:
| Операция | dplyr | DataFrames.jl |
|---|---|---|
Свертка нескольких значений |
|
|
Добавление новых столбцов |
|
|
Выборка и преобразование столбцов |
|
|
В таблице ниже сравниваются более сложные команды.
| Операция | dplyr | DataFrames.jl |
|---|---|---|
Комплексная функция |
|
|
Преобразование нескольких столбцов |
|
|
|
|
|
|
|
|
|
|
|
Многомерная функция |
|
|
Построчная |
|
|
|
|
|
DataFrame в качестве входного объекта |
|
|
DataFrame в качестве выходного объекта |
|
|
Сравнение с пакетом data.table в R
В следующей таблице основные функции пакета DataFrames.jl сравниваются с пакетом R data.table (версии 1.14.1).
library(data.table)
df <- data.table(grp = rep(1:2, 3), x = 6:1, y = 4:9,
z = c(3:7, NA), id = letters[1:6])
df2 <- data.table(grp=c(1,3), w = c(10,11))
| Операция | data.table | DataFrames.jl |
|---|---|---|
Свертка нескольких значений |
|
|
Добавление новых столбцов |
|
|
Переименование столбца (на месте) |
|
|
Переименование нескольких столбцов (на месте) |
|
|
Выборка столбцов в виде фрейма данных |
|
|
Выборка столбца в виде вектора |
|
|
Удаление столбцов |
|
|
Удаление столбцов (на месте) |
|
|
Удаление столбцов (на месте) |
|
|
Выборка и преобразование столбцов |
|
|
Выборка строк |
|
|
Сортировка строк (на месте) |
|
|
Сортировка строк |
|
|
Группирование и агрегирование данных
| Операция | data.table | DataFrames.jl |
|---|---|---|
Свертка нескольких значений |
|
|
Добавление новых столбцов (на месте) |
|
|
Выборка и преобразование столбцов |
|
|
Более сложные команды
| Операция | data.table | DataFrames.jl |
|---|---|---|
Комплексная функция |
|
|
Преобразование некоторых строк (на месте) |
|
|
Преобразование нескольких столбцов |
|
|
|
|
|
|
|
|
|
|
|
Многомерная функция |
|
|
Построчная |
|
|
|
|
|
DataFrame в качестве выходного объекта |
|
|
DataFrame в качестве выходного объекта |
|
|
Объединение фреймов данных
| Операция | data.table | DataFrames.jl |
|---|---|---|
Внутреннее объединение |
|
|
Внешнее объединение |
|
|
Левое объединение |
|
|
Правое объединение |
|
|
Антиобъединение (фильтрация) |
|
|
Полуобъединение (фильтрация) |
|
|
Сравнение со Stata (версии 8 и выше)
В следующей таблице основные функции пакета DataFrames.jl сравниваются со Stata.
| Операция | Stata | DataFrames.jl |
|---|---|---|
Свертка нескольких значений |
|
|
Добавление новых столбцов |
|
|
Переименование столбцов |
|
|
Выборка столбцов |
|
|
Выборка строк |
|
|
Сортировка строк |
|
|
Обратите внимание, что суффикс ! (transform!, select! и т. д.) обеспечивает преобразование фрейма данных на месте, как в Stata.
Некоторые из этих функций могут применяться к сгруппированным фреймам данных; в этом случае они работают с отдельными группами:
| Операция | Stata | DataFrames.jl |
|---|---|---|
Добавление новых столбцов |
|
|
Свертка нескольких значений |
|
|
В таблице ниже сравниваются более сложные команды.
| Операция | Stata | DataFrames.jl |
|---|---|---|
Преобразование некоторых строк |
|
|
Преобразование нескольких столбцов |
|
|
|
|
|
|
|
|
|
|
|
Многомерная функция |
|
|
Построчная |
|
|