Функции

Поддержка многопоточности

По умолчанию некоторые операции в DataFrames.jl автоматически используют несколько потоков, если есть такая возможность. Этот механизм основан на задачах и реализован с помощью макроса @spawn из модуля Base Julia. Функции, которые принимают пользовательские функции и могут выполнять их параллельно, принимают именованный аргумент threads, который позволяет отключать многопоточность, если переданная функция требует последовательного выполнения или не является потокобезопасной.

Вот список операций, в настоящее время использующих многопоточность:

  • конструктор DataFrame с аргументом copycols=true, а также рекурсивно все вызывающие его функции, например copy;

  • getindex при выборе нескольких столбцов;

  • groupby (как в случае, когда требуется хэширование, так и в случае, когда применяется первый путь, использующий DataAPI.refpool);

  • функции *join для составления выходного фрейма данных (но не для нахождения соответствующих строк в объединенных фреймах данных, по крайней мере пока);

  • combine, select[!] и transform[!] для объектов GroupedDataFrame при выполнении любого из следующих условий:

    • выполняется несколько преобразований (для каждого из которых порождается отдельная задача);

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

  • dropmissing, если в переданном фрейме данных более одного столбца и задан аргумент view=false (для разделения отдельных столбцов на подмножества порождаются отдельные задачи).

Как правило, для использования многопоточности требуется версия Julia не ниже 1.4, а процесс Julia должен запускаться более чем с одним потоком. Для некоторых операций многопоточность активируется только в том случае, если в обрабатываемом фрейме данных достаточно строк (конкретное пороговое значение точно не определено и может измениться в будущем).

Кроме операций из приведенного выше списка, для которых многопоточность используется автоматически, все функции из пакета DataFrames.jl, изменяющий фрейм данных, не являются потокобезопасными. Это означает, что, хотя их можно вызывать из любого потока, вызывающая сторона должна гарантировать, что объект DataFrame не будет изменяться каким-либо потоком, пока его используют другие (либо для чтения, либо для записи). Один и тот же объект DataFrame можно безопасно использовать из других потоков при условии, что он не изменяется.

Указатель

Создание фреймов данных

# DataAPI.allcombinationsFunction

allcombinations(DataFrame, pairs::Pair...)
allcombinations(DataFrame; kwargs...)

Create a DataFrame from all combinations of values in passed arguments. The first passed values vary fastest.

Arguments associating a column name with values to expand can be specified either as Pairs passed as positional arguments, or as keyword arguments. Column names must be Symbols or strings and must be unique.

Column value can be a vector which is consumed as is or an object of any other type (except AbstractArray). In the latter case the passed value is treated as having length one for expansion. As a particular rule values stored in a Ref or a 0-dimensional AbstractArray are unwrapped and treated as having length one.

See also: crossjoin can be used to get the cartesian product of rows from passed data frames.

Examples

julia> allcombinations(DataFrame, a=1:2, b='a':'c')
6×2 DataFrame
 Row │ a      b
     │ Int64  Char
─────┼─────────────
   1 │     1  a
   2 │     2  a
   3 │     1  b
   4 │     2  b
   5 │     1  c
   6 │     2  c

julia> allcombinations(DataFrame, "a" => 1:2, "b" => 'a':'c', "c" => "const")
6×3 DataFrame
 Row │ a      b     c
     │ Int64  Char  String
─────┼─────────────────────
   1 │     1  a     const
   2 │     2  a     const
   3 │     1  b     const
   4 │     2  b     const
   5 │     1  c     const
   6 │     2  c     const

# Base.copyFunction

copy(df::DataFrame; copycols::Bool=true)

Copy data frame df. If copycols=true (the default), return a new DataFrame holding copies of column vectors in df. If copycols=false, return a new DataFrame sharing column vectors with df.

Metadata: this function preserves all table-level and column-level metadata.

copy(dfr::DataFrameRow)

Construct a NamedTuple with the same contents as the DataFrameRow. This method returns a NamedTuple so that the returned object is not affected by changes to the parent data frame of which dfr is a view.

copy(key::GroupKey)

Construct a NamedTuple with the same contents as the GroupKey.

# Base.similarFunction

similar(df::AbstractDataFrame, rows::Integer=nrow(df))

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

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Сводная информация

# DataAPI.describeFunction

describe(df::AbstractDataFrame; cols=:)
describe(df::AbstractDataFrame, stats::Union{Symbol, Pair}...; cols=:)

Return descriptive statistics for a data frame as a new DataFrame where each row represents a variable and each column a summary statistic.

Arguments

  • df : the AbstractDataFrame

  • stats::Union{Symbol, Pair}... : the summary statistics to report. Arguments can be:

    • A symbol from the list :mean, :std, :min, :q25, :median, :q75, :max, :sum, :eltype, :nunique, :nuniqueall, :first, :last, :nnonmissing, and :nmissing. The default statistics used are :mean, :min, :median, :max, :nmissing, and :eltype.

    • :detailed as the only Symbol argument to return all statistics except :first, :last, :sum, :nuniqueall, and :nnonmissing.

    • :all as the only Symbol argument to return all statistics.

    • A function => name pair where name is a Symbol or string. This will create a column of summary statistics with the provided name.

  • cols : a keyword argument allowing to select only a subset or transformation of columns from df to describe. Can be any column selector or transformation accepted by select.

Details

For Real columns, compute the mean, standard deviation, minimum, first quantile, median, third quantile, and maximum. If a column does not derive from Real, describe will attempt to calculate all statistics, using nothing as a fall-back in the case of an error.

When stats contains :nunique, describe will report the number of unique values in a column. If a column’s base type derives from Real, :nunique will return nothings. Use :nuniqueall to report the number of unique values in all columns.

Missing values are filtered in the calculation of all statistics, however the column :nmissing will report the number of missing values of that variable and :nnonmissing the number of non-missing values.

If custom functions are provided, they are called repeatedly with the vector corresponding to each column as the only argument. For columns allowing for missing values, the vector is wrapped in a call to skipmissing: custom functions must therefore support such objects (and not only vectors), and cannot access missing values.

Metadata: this function drops all metadata.

Examples

julia> df = DataFrame(i=1:10, x=0.1:0.1:1.0, y='a':'j');

julia> describe(df)
3×7 DataFrame
 Row │ variable  mean    min  median  max  nmissing  eltype
     │ Symbol    Union…  Any  Union…  Any  Int64     DataType
─────┼────────────────────────────────────────────────────────
   1 │ i         5.5     1    5.5     10          0  Int64
   2 │ x         0.55    0.1  0.55    1.0         0  Float64
   3 │ y                 a            j           0  Char

julia> describe(df, :min, :max)
3×3 DataFrame
 Row │ variable  min  max
     │ Symbol    Any  Any
─────┼────────────────────
   1 │ i         1    10
   2 │ x         0.1  1.0
   3 │ y         a    j

julia> describe(df, :min, sum => :sum)
3×3 DataFrame
 Row │ variable  min  sum
     │ Symbol    Any  Union…
─────┼───────────────────────
   1 │ i         1    55
   2 │ x         0.1  5.5
   3 │ y         a

julia> describe(df, :min, sum => :sum, cols=:x)
1×3 DataFrame
 Row │ variable  min      sum
     │ Symbol    Float64  Float64
─────┼────────────────────────────
   1 │ x             0.1      5.5

# Base.isemptyFunction

isempty(df::AbstractDataFrame)

Возвращает true, если фрейм данных df не содержит строк. Возвращает false в противном случае.

# Base.lengthFunction

length(dfr::DataFrameRow)

Return the number of elements of dfr.

See also: size

Examples

julia> dfr = DataFrame(a=1:3, b='a':'c')[1, :]
DataFrameRow
 Row │ a      b
     │ Int64  Char
─────┼─────────────
   1 │     1  a

julia> length(dfr)
2

# DataAPI.ncolFunction

ncol(df::AbstractDataFrame)

Return the number of columns in an AbstractDataFrame df.

See also nrow, size.

Examples

julia> df = DataFrame(i=1:10, x=rand(10), y=rand(["a", "b", "c"], 10));

julia> ncol(df)
3

# Base.ndimsFunction

ndims(::AbstractDataFrame)
ndims(::Type{<:AbstractDataFrame})

Возвращает количество измерений фрейма данных, которое всегда равно 2.

ndims(::DataFrameRow)
ndims(::Type{<:DataFrameRow})

Возвращает количество измерений строки фрейма данных, которое всегда равно 1.

# DataAPI.nrowFunction

nrow(df::AbstractDataFrame)

Return the number of rows in an AbstractDataFrame df.

See also: ncol, size.

Examples

julia> df = DataFrame(i=1:10, x=rand(10), y=rand(["a", "b", "c"], 10));

julia> nrow(df)
10

# DataAPI.rownumberFunction

rownumber(dfr::DataFrameRow)

Return a row number in the AbstractDataFrame that dfr was created from.

Note that this differs from the first element in the tuple returned by parentindices. The latter gives the row number in the parent(dfr), which is the source DataFrame where data that dfr gives access to is stored.

Examples

julia> df = DataFrame(reshape(1:12, 3, 4), :auto)
3×4 DataFrame
 Row │ x1     x2     x3     x4
     │ Int64  Int64  Int64  Int64
─────┼────────────────────────────
   1 │     1      4      7     10
   2 │     2      5      8     11
   3 │     3      6      9     12

julia> dfr = df[2, :]
DataFrameRow
 Row │ x1     x2     x3     x4
     │ Int64  Int64  Int64  Int64
─────┼────────────────────────────
   2 │     2      5      8     11

julia> rownumber(dfr)
2

julia> parentindices(dfr)
(2, Base.OneTo(4))

julia> parent(dfr)
3×4 DataFrame
 Row │ x1     x2     x3     x4
     │ Int64  Int64  Int64  Int64
─────┼────────────────────────────
   1 │     1      4      7     10
   2 │     2      5      8     11
   3 │     3      6      9     12

julia> dfv = @view df[2:3, 1:3]
2×3 SubDataFrame
 Row │ x1     x2     x3
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     2      5      8
   2 │     3      6      9

julia> dfrv = dfv[2, :]
DataFrameRow
 Row │ x1     x2     x3
     │ Int64  Int64  Int64
─────┼─────────────────────
   3 │     3      6      9

julia> rownumber(dfrv)
2

julia> parentindices(dfrv)
(3, 1:3)

julia> parent(dfrv)
3×4 DataFrame
 Row │ x1     x2     x3     x4
     │ Int64  Int64  Int64  Int64
─────┼────────────────────────────
   1 │     1      4      7     10
   2 │     2      5      8     11
   3 │     3      6      9     12

# Base.showFunction

show([io::IO, ]df::AbstractDataFrame;
     allrows::Bool = !get(io, :limit, false),
     allcols::Bool = !get(io, :limit, false),
     allgroups::Bool = !get(io, :limit, false),
     rowlabel::Symbol = :Row,
     summary::Bool = true,
     eltypes::Bool = true,
     truncate::Int = 32,
     kwargs...)

Отрисовывает фрейм данных в поток ввода-вывода. Выбор конкретного визуального представления зависит от ширины дисплея.

Если io пропущен, результат выводится в stdout и allrows, allcols и allgroups по умолчанию имеют значение false.

Аргументы

  • io::IO: поток ввода-вывода, в который будет выведено значение df.

  • df::AbstractDataFrame: выводимый фрейм данных.

  • allrows::Bool: нужно ли выводить все строки, а не подмножество, соответствующее высоте устройства. По умолчанию используется только в том случае, если для io не задано ограничение (limit) свойства IOContext.

  • allcols::Bool: нужно ли выводить все столбцы, а не подмножество, соответствующее ширине устройства. По умолчанию используется только в том случае, если для io не задано ограничение (limit) свойства IOContext.

  • allgroups::Bool: нужно ли выводить все группы, а не первую и последнюю, когда df является GroupedDataFrame. По умолчанию используется только в том случае, если для io не задано свойство IOContext limit.

  • rowlabel::Symbol = :Row: метка, используемая для столбца с номерами строк.

  • summary::Bool = true: нужно ли выводить краткое строковое описание фрейма данных.

  • eltypes::Bool = true: нужно ли выводить типы столбцов под именами столбцов.

  • truncate::Int = 32: максимальная ширина дисплея, которую может использовать вывод перед усечением (в смысле textwidth, без учета ). Если truncate имеет значение 0 или меньше, усечение не применяется.

  • kwargs...: сюда можно передать любой именованный аргумент, поддерживаемый функцией pretty_table пакета PrettyTables.jl, чтобы настроить вывод.

Примеры

julia> using DataFrames

julia> df = DataFrame(A=1:3, B=["x", "y", "z"]);

julia> show(df, show_row_number=false)
3×2 DataFrame
 A      B
 Int64  String
───────────────
     1  x
     2  y
     3  z
show(io::IO, mime::MIME, df::AbstractDataFrame)

Отрисовывает фрейм данных в поток ввода-вывода в типе MIME mime.

Аргументы

  • io::IO: поток ввода-вывода, в который будет выведено значение df.

  • mime::MIME: поддерживаются следующие типы MIME: "text/plain", "text/html", "text/latex", "text/csv", "text/tab-separated-values" (последние два типа MIME не поддерживают отображение значений #undef).

  • df::AbstractDataFrame: выводимый фрейм данных.

Дополнительно выбранные типы MIME поддерживают передачу следующих именованных аргументов:

  • Тип MIME "text/plain" принимает все перечисленные именованные аргументы, и их поведение идентично для show(::IO, ::AbstractDataFrame).

  • Тип MIME "text/html" принимает следующие именованные аргументы:

    • eltypes::Bool = true: нужно ли выводить типы столбцов под именами столбцов.

    • summary::Bool = true: нужно ли выводить краткое строковое описание фрейма данных.

    • max_column_width::AbstractString = "": максимальная ширина столбца. Это должна быть строка, содержащая допустимую длину CSS. Например, если передать значение 100px, ширина всех столбцов будет ограничена 100 пикселями. Если значение пусто, столбцы будут отрисовываться без ограничений.

    • kwargs...: сюда можно передать любой именованный аргумент, поддерживаемый функцией pretty_table пакета PrettyTables.jl, чтобы настроить вывод.

Примеры

julia> show(stdout, MIME("text/latex"), DataFrame(A=1:3, B=["x", "y", "z"]))
\begin{tabular}{r|cc}
	& A & B\
	\hline
	& Int64 & String\
	\hline
	1 & 1 & x \
	2 & 2 & y \
	3 & 3 & z \
\end{tabular}
14

julia> show(stdout, MIME("text/csv"), DataFrame(A=1:3, B=["x", "y", "z"]))
"A","B"
1,"x"
2,"y"
3,"z"

# Base.sizeFunction

size(df::AbstractDataFrame[, dim])

Возвращает кортеж, содержащий количество строк и столбцов df. При желании можно указать измерение dim, где 1 соответствует строкам, а 2 — столбцам.

См. также описание nrow, ncol

Примеры

julia> df = DataFrame(a=1:3, b='a':'c');

julia> size(df)
(3, 2)

julia> size(df, 1)
3
size(dfr::DataFrameRow[, dim])

Возвращает 1 кортеж, содержащий количество элементов dfr. Если указано необязательное измерение dim, оно должно быть 1, а количество элементов возвращается непосредственно в виде числа.

См. также описание length

Примеры

julia> dfr = DataFrame(a=1:3, b='a':'c')[1, :]
DataFrameRow
 Row │ a      b
     │ Int64  Char
─────┼─────────────
   1 │     1  a

julia> size(dfr)
(2,)

julia> size(dfr, 1)
2

Работа с именами столбцов

# Base.namesFunction

names(df::AbstractDataFrame, cols=:)
names(df::DataFrameRow, cols=:)
names(df::GroupedDataFrame, cols=:)
names(df::DataFrameRows, cols=:)
names(df::DataFrameColumns, cols=:)
names(df::GroupKey)

Возвращает только что выделенный Vector{String} имен столбцов, содержащихся в df.

Если передан cols, ограничьте возвращаемые имена столбцов теми, что соответствуют селектору (это полезно, в частности, при использовании регулярных выражений, Cols, Not и Between). cols может представлять собой:

  • любой селектор столбцов (символ (Symbol), строку или целое число; :, Cols, All, Between, Not, регулярное выражение или вектор символов (Symbol), строк или целых чисел); эти селекторы строк документированы в разделе важных правил в части Индексирование руководства по DataFrames.jl

  • тип (Type), в этом случае возвращаются имена столбцов, eltype которых является подтипом T

  • предикат функции (Function), принимающий имя столбца в виде строки и возвращающий true для столбцов, которые должны быть сохранены

См. также описание функции propertynames, которая возвращает Vector{Symbol}.

Примеры

julia> df = DataFrame(x1=[1, missing, missing], x2=[3, 2, 4], x3=[3, missing, 2], x4=Union{Int, Missing}[2, 4, 4])
3×4 DataFrame
 Row │ x1       x2     x3       x4
     │ Int64?   Int64  Int64?   Int64?
─────┼─────────────────────────────────
   1 │       1      3        3       2
   2 │ missing      2  missing       4
   3 │ missing      4        2       4

julia> names(df)
4-element Vector{String}:
 "x1"
 "x2"
 "x3"
 "x4"

julia> names(df, Int) # выбор столбцов с типом элемента Int
1-element Vector{String}:
 "x2"

julia> names(df, x -> x[end] == '2') # выбор столбцов, для которых последний символ в их имени равен 2
1-element Vector{String}:
 "x2"

julia> fun(col) = sum(skipmissing(col)) >= 10
fun (generic function with 1 method)

julia> names(df, fun.(eachcol(df))) # выбор столбцов, сумма элементов которых не меньше 10
1-element Vector{String}:
 "x4"

julia> names(df, eltype.(eachcol(df)) .>: Missing) # выбор столбцов, допускающих отсутствующие значения
3-element Vector{String}:
 "x1"
 "x3"
 "x4"

julia> names(df, any.(ismissing, eachcol(df))) # выбор столбцов, содержащих отсутствующие значения
2-element Vector{String}:
 "x1"
 "x3"

# Base.propertynamesFunction

propertynames(df::AbstractDataFrame)

Возвращает только что выделенный Vector{Symbol} имен столбцов, содержащихся в df.

# DataFrames.renameFunction

rename(df::AbstractDataFrame, vals::AbstractVector{Symbol};
       makeunique::Bool=false)
rename(df::AbstractDataFrame, vals::AbstractVector{<:AbstractString};
       makeunique::Bool=false)
rename(df::AbstractDataFrame, (from => to)::Pair...)
rename(df::AbstractDataFrame, d::AbstractDict)
rename(df::AbstractDataFrame, d::AbstractVector{<:Pair})
rename(f::Function, df::AbstractDataFrame)

Создает новый фрейм данных, который является копией df с измененными именами столбцов. Каждое имя может быть изменено не более одного раза. Допускается перестановка имен.

Аргументы

  • df: AbstractDataFrame; если это SubDataFrame, переименование разрешено только в том случае, если он был создан с использованием : в качестве селектора столбцов.

  • d: AbstractDict или AbstractVector пар (Pair), которые сопоставляют исходные имена или номера столбцов с новыми именами.

  • f: функция, которая для каждого столбца принимает старое имя в виде строки (String) и возвращает новое имя, которое преобразуется в символ (Symbol).

  • vals: новые имена столбцов в виде вектора символов (Symbol) или строк (AbstractString) той же длины, что и количество столбцов в df.

  • makeunique: если задано значение false (по умолчанию), возникает ошибка при обнаружении повторяющихся имен; если задано значение true, к повторяющимся именам добавляется суффикс _i (i, начиная с 1 для первого повторяющегося имени).

Если в rename передаются пары (как позиционные аргументы, в словаре или векторе), то:

  • значение from может быть Symbol, AbstractString или Integer;

  • значение to может быть Symbol или AbstractString.

Смешивание символов и строк в to и from не допускается.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Метаданные на уровне столбцов в стиле :note считаются прикрепленными к номеру столбца: когда столбец переименовывается, его метаданные в стиле :note становятся связанными с его новым именем.

См. также описание rename!.

Примеры

julia> df = DataFrame(i=1, x=2, y=3)
1×3 DataFrame
 Row │ i      x      y
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      2      3

julia> rename(df, [:a, :b, :c])
1×3 DataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      2      3

julia> rename(df, :i => "A", :x => "X")
1×3 DataFrame
 Row │ A      X      y
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      2      3

julia> rename(df, :x => :y, :y => :x)
1×3 DataFrame
 Row │ i      y      x
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      2      3

julia> rename(df, [1 => :A, 2 => :X])
1×3 DataFrame
 Row │ A      X      y
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      2      3

julia> rename(df, Dict("i" => "A", "x" => "X"))
1×3 DataFrame
 Row │ A      X      y
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      2      3

julia> rename(uppercase, df)
1×3 DataFrame
 Row │ I      X      Y
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      2      3

# DataFrames.rename!Function

rename!(df::AbstractDataFrame, vals::AbstractVector{Symbol};
        makeunique::Bool=false)
rename!(df::AbstractDataFrame, vals::AbstractVector{<:AbstractString};
        makeunique::Bool=false)
rename!(df::AbstractDataFrame, (from => to)::Pair...)
rename!(df::AbstractDataFrame, d::AbstractDict)
rename!(df::AbstractDataFrame, d::AbstractVector{<:Pair})
rename!(f::Function, df::AbstractDataFrame)

Переименовывает столбцы df на месте. Каждое имя может быть изменено не более одного раза. Допускается перестановка имен.

Аргументы

  • df: AbstractDataFrame.

  • d: AbstractDict или AbstractVector пар (Pair), которые сопоставляют исходные имена или номера столбцов с новыми именами.

  • f: функция, которая для каждого столбца принимает старое имя в виде строки (String) и возвращает новое имя, которое преобразуется в символ (Symbol).

  • vals: новые имена столбцов в виде вектора символов (Symbol) или строк (AbstractString) той же длины, что и количество столбцов в df.

  • makeunique: если задано значение false (по умолчанию), возникает ошибка при обнаружении повторяющихся имен; если задано значение true, к повторяющимся именам добавляется суффикс _i (i, начиная с 1 для первого повторяющегося имени).

Если в rename! передаются пары (как позиционные аргументы, в словаре или векторе), то:

  • значение from может быть Symbol, AbstractString или Integer;

  • значение to может быть Symbol или AbstractString.

Смешивание символов и строк в to и from не допускается.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Метаданные, имеющие другие стили, удаляются (из родительского фрейма данных, если df является SubDataFrame). Метаданные на уровне столбцов в стиле :note считаются прикрепленными к номеру столбца: когда столбец переименовывается, его метаданные в стиле :note становятся связанными с его новым именем.

См. также описание rename.

Примеры

julia> df = DataFrame(i=1, x=2, y=3)
1×3 DataFrame
 Row │ i      x      y
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      2      3

julia> rename!(df, Dict(:i => "A", :x => "X"))
1×3 DataFrame
 Row │ A      X      y
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      2      3

julia> rename!(df, [:a, :b, :c])
1×3 DataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      2      3

julia> rename!(df, [:a, :b, :a])
ERROR: ArgumentError: Duplicate variable names: :a. Pass makeunique=true to make them unique using a suffix automatically.

julia> rename!(df, [:a, :b, :a], makeunique=true)
1×3 DataFrame
 Row │ a      b      a_1
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      2      3

julia> rename!(uppercase, df)
1×3 DataFrame
 Row │ A      B      A_1
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      2      3

Изменение и преобразование фреймов данных и сгруппированных фреймов данных

# Base.append!Function

append!(df::DataFrame, df2::AbstractDataFrame; cols::Symbol=:setequal,
        promote::Bool=(cols in [:union, :subset]))
append!(df::DataFrame, table; cols::Symbol=:setequal,
        promote::Bool=(cols in [:union, :subset]))

Добавляет строки df2 в конец df. Если второй аргумент table не является AbstractDataFrame, он преобразуется с помощью DataFrame(table, copycols=false) и только затем добавляется.

Точное поведение append! зависит от аргумента cols.

  • Если cols == :setequal (по умолчанию), df2 должен содержать именно те же столбцы, что и df (но, возможно, в другом порядке).

  • Если cols == :orderequal, df2 должна содержать те же столбцы в том же порядке (для AbstractDict этот параметр требует, чтобы keys(row) совпадал с propertynames(df) в целях поддержки упорядоченных словарей. Однако если df2 является словарем (Dict), возникает ошибка, так как это неупорядоченная коллекция).

  • Если cols == :intersect, df2 должен содержать больше столбцов, чем df, но все имена столбцов, имеющиеся в df, должны присутствовать и в df2, и только они используются.

  • Если cols == :subset, append! действует как для :intersect, но если какой-то столбец отсутствует в df2, отсутствующее (missing) значение отправляется в df.

  • Если cols == :union, append! добавляет столбцы, отсутствующие в df, которые присутствуют в df2, для столбцов, присутствующих в df, но отсутствующих в df2, отправляется значение missing .

Если promote=true и тип элемента столбца, присутствующего в df, запрещает использовать тип отправляемого элемента, новый столбец с продвинутым типом элемента, разрешающим этот тип, выделяется заново и сохраняется в df. Если promote=false, возникает ошибка .

Из этого правила есть следующие исключения.

  • Если df не имеет столбцов, к нему добавляются копии столбцов из df2.

  • Если df2 не имеет столбцов, вызов append! оставляет df без изменений.

Обратите внимание, что append! нельзя использовать для DataFrame, содержащего столбцы, которые являются псевдонимами (одинаковыми при сравнении ===).

Метаданные: метаданные на уровне таблиц в стиле :note и метаданные на уровне столбцов в стиле :note для столбцов, присутствующих в df, сохраняются. При добавлении новых столбцов их метаданные в стиле :note копируются из добавляемой таблицы. Другие метаданные удаляются.

См. также: использование push! для добавления отдельных строк к фрейму данных, prepend! для добавления таблицы в начало и vcat для вертикальной конкатенации фреймов данных.

Примеры

julia> df1 = DataFrame(A=1:3, B=1:3)
3×2 DataFrame
 Row │ A      B
     │ Int64  Int64
─────┼──────────────
   1 │     1      1
   2 │     2      2
   3 │     3      3

julia> df2 = DataFrame(A=4.0:6.0, B=4:6)
3×2 DataFrame
 Row │ A        B
     │ Float64  Int64
─────┼────────────────
   1 │     4.0      4
   2 │     5.0      5
   3 │     6.0      6

julia> append!(df1, df2);

julia> df1
6×2 DataFrame
 Row │ A      B
     │ Int64  Int64
─────┼──────────────
   1 │     1      1
   2 │     2      2
   3 │     3      3
   4 │     4      4
   5 │     5      5
   6 │     6      6

# DataFrames.combineFunction

combine(df::AbstractDataFrame, args...;
        renamecols::Bool=true, threads::Bool=true)
combine(f::Callable, df::AbstractDataFrame;
        renamecols::Bool=true, threads::Bool=true)
combine(gd::GroupedDataFrame, args...;
        keepkeys::Bool=true, ungroup::Bool=true,
        renamecols::Bool=true, threads::Bool=true)
combine(f::Base.Callable, gd::GroupedDataFrame;
        keepkeys::Bool=true, ungroup::Bool=true,
        renamecols::Bool=true, threads::Bool=true)

Создает новый фрейм данных, содержащий столбцы из df или gd, указанные с помощью args, и возвращает его. Результат может содержать любое количество строк, которое определяется значениями, возвращаемыми переданными преобразованиями.

Ниже подробно описаны и сопоставлены общие правила для всех функций преобразования, поддерживаемых DataFrames.jl.

Все эти операции поддерживаются как для AbstractDataFrame (при пропуске шагов разделения и объединения), так и для GroupedDataFrame. Технически AbstractDataFrame считается сгруппированным без столбцов (это означает, что у него есть одна группа или ни одной, если он пуст). Единственное отличие заключается в том, что в этом случае именованные аргументы keepkeys и ungroup (описанные ниже) не поддерживаются, и всегда возвращается фрейм данных, поскольку в этом случае нет шагов разделения и объединения.

Чтобы выполнять операции с группами, сначала нужно создать объект GroupedDataFrame из фрейма данных с помощью функции groupby, которая принимает два аргумента: (1) фрейм данных, который нужно сгруппировать, и (2) набор столбцов, по которым осуществляется группировка.

Затем можно применить операции к каждой группе с помощью одной из следующих функций:

  • combine: не накладывает ограничений на количество возвращаемых строк в каждой группе; возвращаемые значения конкатенируются по вертикали в соответствии с порядком групп в GroupedDataFrame; обычно используется для вычисления сводной статистики по группам; для GroupedDataFrame, если группирующие столбцы сохраняются, они помещаются первыми в результат;

  • select: возвращает фрейм данных с количеством и порядком строк, точно таким же, как в исходном фрейме данных, включая только новые вычисленные столбцы; select! является версией на месте для select; для GroupedDataFrame, если группирующие столбцы сохраняются, они помещаются первыми в результат;

  • transform: возвращает фрейм данных с количеством и порядком строк, точно таким же, как в исходном фрейме данных, включая все столбцы из исходного фрейма и новые вычисленные столбцы; transform! является версией на месте для transform; существующие столбцы в исходном фрейме данных помещаются первыми в результат.

Особый случай: если передается GroupedDataFrame без групп, результат операции определяется путем выполнения одного вызова функции преобразования с переданным ей аргументом с нулем строк. Выходные данные этой операции используются только для определения количества и типа созданных столбцов, но результат не содержит строк.

Все эти функции принимают спецификацию одной или нескольких функций для применения к каждому подмножеству DataFrame. Эта спецификация может иметь следующий вид:

  1. Стандартные селекторы столбцов (целые числа, символы (Symbol), строки, векторы целых чисел, векторы символов (Symbol), векторы строк, All, Cols, :, Between, Not и регулярные выражения).

  2. Пара cols => function, указывающая, что функцию (function) следует вызывать с позиционными аргументами, содержащими столбцы cols, которые могут быть любым допустимым селектором столбцов. В этом случае имя целевого столбца генерируется автоматически и предполагается, что функция (function) возвращает единичное значение или вектор. Сгенерированное имя создается путем конкатенации имени исходного столбца и имени функции (function) по умолчанию (см. примеры ниже).

  3. Форма cols => function => target_cols, дополнительно явно указывающая целевой столбец или столбцы, которые должны быть одним именем (как Symbol или строка), вектором имен или AsTable. Кроме того, это может быть функция (Function), которая принимает в качестве аргумента строку или вектор строк, содержащие имена столбцов, выбранные с помощью cols, и возвращает имена целевых столбцов (допускаются все принятые типы, кроме AsTable).

  4. Пара col => target_cols, которая переименовывает столбец col в target_cols, который должен быть одним именем (как Symbol или строка), вектором имен или AsTable.

  5. Независимые от столбцов операции function => target_cols или просто function для конкретных функций (function), где входные столбцы опущены; без target_cols новый столбец имеет то же имя, что и function, в противном случае должен быть одним именем (как Symbol или строка). Поддерживаются следующие функции (function).

    • nrow для эффективного вычисления количества строк в каждой группе.

    • proprow для эффективного вычисления доли строк в каждой группе.

    • eachindex для возврата вектора, содержащего номер каждой строки в каждой группе.

    • groupindices для возврата номера группы.

  6. Векторы или матрицы, содержащие преобразования, заданные синтаксисом Pair, описываются в пунктах 2—​5.

  7. Функция, которая будет вызвана с SubDataFrame, соответствующим каждой группе, если обрабатывается GroupedDataFrame, или с самим фреймом данных, если обрабатывается AbstractDataFrame. Эту форму не рекомендуется использовать из-за ее низкой производительности, за исключением случаев, когда количество групп невелико или обрабатывается очень большое количество столбцов (в этом случае SubDataFrame позволяет избежать чрезмерной компиляции).

Примечание. Если передается выражение вида x => y, то, за исключением специального вспомогательного вида nrow => target_cols, оно всегда интерпретируется как cols => function. В частности, следующее выражение function => target_cols не является допустимой спецификацией преобразования.

Примечание. Если cols или target_cols являются All, Cols, Between или Not, поддерживается трансляция с использованием .=>, и она эквивалентна трансляции результата names(df, cols) или names(df, target_cols). Это работает, как будто трансляция произошла после замены селектора выбранными именами столбцов в области фрейма данных.

Все функции имеют два типа сигнатур. Один из них принимает GroupedDataFrame в качестве первого аргумента и произвольное количество преобразований, описанных выше, в качестве последующих аргументов. Второй тип сигнатуры — это когда в качестве первого аргумента передается Function или Type и GroupedDataFrame в качестве второго аргумента (аналогично map).

Есть особое правило: если при использовании синтаксисов cols => function и cols => function => target_cols cols заключен в объект AsTable, NamedTuple, содержащий столбцы, выбранные с помощью cols, передается функции (function). Дополнительные сведения см. в документации по DataFrames.table_transformation, где также рассматриваются вопросы производительности.

Результат, который может возвращать функция (function), определяется значением target_cols.

  1. Если cols и target_cols опущены (передается только function), при возврате фрейма данных, матрицы, NamedTuple, Tables.AbstractRow или DataFrameRow будет создано несколько столбцов. При возврате любого другого значения создается один столбец.

  2. Если target_cols является символом (Symbol) или строкой, предполагается, что функция возвратит один столбец. В этом случае при возврате фрейма данных, матрицы, NamedTuple, Tables.AbstractRow или DataFrameRow возникнет ошибка.

  3. Если target_cols является вектором символов (Symbol) или строк или AsTable, предполагается, что функция (function) возвратит несколько столбцов. Если функция (function) возвращает какой-либо элемент из AbstractDataFrame, NamedTuple, DataFrameRow, Tables.AbstractRow, AbstractMatrix, применяется правило, описанное в пункте 1 выше. Если функция (function) возвращает AbstractVector, каждый элемент этого вектора должен поддерживать функцию keys, которая должна возвращать коллекцию Symbol, строк или целых чисел. Возвращаемое значение keys должно быть одинаковым для всех элементов. Затем создается столько столбцов, сколько элементов содержится в возвращаемом значении функции keys. Если target_cols является AsTable, их имена задаются равными именам ключей, за исключением случаев, когда keys возвращает целые числа, тогда они получают префикс x (таким образом, имена столбцов будут выглядеть как x1, x2 и т. д.). Если target_cols является вектором символов (Symbol) или строк, имена столбцов, созданные на основе приведенных выше правил, игнорируются и заменяются target_cols (в этом случае количество столбцов должно совпадать с длиной target_cols). Если fun возвращает значение любого другого типа, предполагается, что это таблица, соответствующая API Tables.jl, и для нее вызывается функция Tables.columntable для получения результирующих столбцов и их имен. Имена сохраняются, когда target_cols является AsTable, и заменяются, если target_cols является вектором символов (Symbol) или строк.

Во всех этих случаях функция (function) может возвращать как одну строку, так и несколько. Как правило, значения, заключенные в Ref или 0-мерный массив AbstractArray, распаковываются и после этого считаются одной строкой.

select/select! и transform/transform! всегда возвращают фрейм данных с количеством и порядком строк, точно таким же, как у исходного (даже если в GroupedDataFrame был изменен порядок групп), за исключением случаев, когда в результирующем фрейме данных нет столбцов (в этом случае результат не содержит строк).

Для combine строки в возвращаемом объекте отображаются в порядке групп в GroupedDataFrame. Функции могут возвращать произвольное количество строк для каждой группы, но тип возвращаемого объекта и количество и имена столбцов должны быть одинаковыми для всех групп, за исключением случаев, когда возвращаются DataFrame() или NamedTuple(), тогда заданная группа пропускается.

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

Чтобы применить функцию (function) к каждой строке, а не ко всем столбцам, ее можно заключить в структуру ByRow. cols может быть любым синтаксисом индексирования столбцов. Тогда функции (function) будет передан один аргумент для каждого из столбцов, указанных с помощью cols, или NamedTuple, если указанные столбцы заключены в AsTable. Если используется ByRow, cols может выбрать пустой набор столбцов, тогда function вызывается для каждой строки без аргументов, и передается пустой NamedTuple, если в AsTable заключен пустой набор столбцов.

Если передается коллекция имен столбцов, то принимаются запросы дублирующихся имен столбцов в целевом фрейме данных (например, допускается select!(df, [:a], :, r"a")), и используется только первое вхождение. В частности, используется следующий синтаксис для перемещения столбца :col в первую позицию во фрейме данных — select!(df, :col, :). Напротив, имена выходных столбцов в операциях переименования, преобразования и выбора одного столбца должны быть уникальными, поэтому, например, select!(df, :a, :a => :a) или select!(df, :a, :a => ByRow(sin) => :a) недопустимы.

В общем случае столбцы, возвращаемые преобразованиями, сохраняются в целевом фрейме данных без копирования. Исключением из этого правила являются случаи, когда столбцы из исходного фрейма данных повторно используются в целевом фрейме данных. Это можно сделать с помощью таких выражений, как: :x1, [:x1, :x2], :x1 => :x2, :x1 => identity => :x2 или :x1 => (x -> @view x[inds]) (обратите внимание, что в последнем случае исходный столбец используется повторно косвенным образом через представление). В таких случаях поведение зависит от значения именованного аргумента copycols:

  • если copycols=true, в результате таких преобразований всегда создается копия исходного столбца или его представления;

  • если copycols=false, копии создаются только для того, чтобы избежать многократного хранения одного и того же столбца в целевом фрейме данных. Точнее, при первом использовании столбца копирование не производится, но при каждом последующем повторном использовании исходного столбца (при сравнении с использованием ===, которое исключает представления исходных столбцов) создается копия.

Обратите внимание, что при выполнении transform! или select! предполагается, что copycols=false.

Если df является SubDataFrame и copycols=true, возвращается DataFrame и применяются те же правила копирования, что и для входных данных DataFrame: это означает, в частности, что выбранные столбцы будут скопированы. При copycols=false SubDataFrame возвращается без копирования столбцов, и в этом случае преобразование или переименование столбцов не допускается.

Если передается GroupedDataFrame и threads=true (по умолчанию), для каждого указанного преобразования порождается отдельная задача. Затем каждое преобразование порождает столько задач, сколько потоков доступно в Julia, и разделяет обработку групп между ними (однако в настоящее время преобразования с оптимизированной реализацией, такие как sum, и преобразования, возвращающие несколько строк, используют одну задачу для всех групп). Это позволяет выполнять параллельную работу, если среда Julia была запущена с несколькими потоками. Поэтому передаваемые функции преобразования не должны изменять глобальные переменные (то есть они должны быть чистыми), использовать блокировки для управления параллельным доступом, либо следует передать threads=false, чтобы отключить многопоточность. В будущем параллелизм может быть распространен и на другие случаи, так что это требование справедливо и для входных данных DataFrame.

Для повышения производительности операций некоторые преобразования используют оптимизированную реализацию. Дополнительные сведения см. в описании DataFrames.table_transformation.

Именованные аргументы

  • renamecols::Bool=true: должны ли автоматически генерируемые имена столбцов в форме cols => function включать название функций преобразования, или нет.

  • keepkeys::Bool=true: должны ли группирующие столбцы gd сохраняться в возвращаемом фрейме данных.

  • ungroup::Bool=true: должно ли возвращаемое значение операции с gd быть фреймом данных или GroupedDataFrame.

  • threads::Bool=true: могут ли преобразования осуществляться в отдельных задачах, которые могут выполняться параллельно (возможно, с применением к нескольким строкам или группам одновременно). Тот момент, порождаются ли задачи, и их количество определяется автоматически. Установите значение false, если некоторые преобразования требуют последовательного выполнения или не являются потокобезопасными.

Метаданные: эта функция распространяет метаданные на уровне таблиц в стиле :note. Метаданные на уровне столбцов в стиле :note распространяются в следующих случаях: а) один столбец преобразуется в один столбец, при этом имя столбца не изменяется (это относится ко всем операциям выбора столбца), или б) один столбец преобразуется с помощью identity или copy в один столбец даже при изменении имени столбца (сюда относится и переименование столбца). Особый случай для GroupedDataFrame: если вывод имеет то же имя, что и группирующий столбец, и keepkeys=true, метаданные берутся из исходного группирующего столбца.

Примеры

julia> df = DataFrame(a=1:3, b=4:6)
3×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      4
   2 │     2      5
   3 │     3      6

julia> combine(df, :a => sum, nrow, renamecols=false)
1×2 DataFrame
 Row │ a      nrow
     │ Int64  Int64
─────┼──────────────
   1 │     6      3

julia> combine(df, :a => ByRow(sin) => :c, :b)
3×2 DataFrame
 Row │ c         b
     │ Float64   Int64
─────┼─────────────────
   1 │ 0.841471      4
   2 │ 0.909297      5
   3 │ 0.14112       6

julia> combine(df, :, [:a, :b] => (a, b) -> a .+ b .- sum(b)/length(b))
3×3 DataFrame
 Row │ a      b      a_b_function
     │ Int64  Int64  Float64
─────┼────────────────────────────
   1 │     1      4           0.0
   2 │     2      5           2.0
   3 │     3      6           4.0

julia> combine(df, All() .=> [minimum maximum])
1×4 DataFrame
 Row │ a_minimum  b_minimum  a_maximum  b_maximum
     │ Int64      Int64      Int64      Int64
─────┼────────────────────────────────────────────
   1 │         1          4          3          6

julia> using Statistics

julia> combine(df, AsTable(:) => ByRow(mean), renamecols=false)
3×1 DataFrame
 Row │ a_b
     │ Float64
─────┼─────────
   1 │     2.5
   2 │     3.5
   3 │     4.5

julia> combine(df, AsTable(:) => ByRow(mean) => x -> join(x, "_"))
3×1 DataFrame
 Row │ a_b
     │ Float64
─────┼─────────
   1 │     2.5
   2 │     3.5
   3 │     4.5

julia> combine(first, df)
1×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      4

julia> df = DataFrame(a=1:3, b=4:6, c=7:9)
3×3 DataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      4      7
   2 │     2      5      8
   3 │     3      6      9

julia> combine(df, AsTable(:) => ByRow(x -> (mean=mean(x), std=std(x))) => :stats,
               AsTable(:) => ByRow(x -> (mean=mean(x), std=std(x))) => AsTable)
3×3 DataFrame
 Row │ stats                    mean     std
     │ NamedTup…                Float64  Float64
─────┼───────────────────────────────────────────
   1 │ (mean = 4.0, std = 3.0)      4.0      3.0
   2 │ (mean = 5.0, std = 3.0)      5.0      3.0
   3 │ (mean = 6.0, std = 3.0)      6.0      3.0

julia> df = DataFrame(a=repeat([1, 2, 3, 4], outer=[2]),
                      b=repeat([2, 1], outer=[4]),
                      c=1:8);

julia> gd = groupby(df, :a);

julia> combine(gd, :c => sum, nrow)
4×3 DataFrame
 Row │ a      c_sum  nrow
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      6      2
   2 │     2      8      2
   3 │     3     10      2
   4 │     4     12      2

julia> combine(gd, :c => sum, nrow, ungroup=false)
GroupedDataFrame with 4 groups based on key: a
First Group (1 row): a = 1
 Row │ a      c_sum  nrow
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      6      2
⋮
Last Group (1 row): a = 4
 Row │ a      c_sum  nrow
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     4     12      2

julia> combine(gd) do d # синтаксис do для более медленного варианта
           sum(d.c)
       end
4×2 DataFrame
 Row │ a      x1
     │ Int64  Int64
─────┼──────────────
   1 │     1      6
   2 │     2      8
   3 │     3     10
   4 │     4     12

julia> combine(gd, :c => (x -> sum(log, x)) => :sum_log_c) # указание имени для целевого столбца
4×2 DataFrame
 Row │ a      sum_log_c
     │ Int64  Float64
─────┼──────────────────
   1 │     1    1.60944
   2 │     2    2.48491
   3 │     3    3.04452
   4 │     4    3.46574

julia> combine(gd, [:b, :c] .=> sum) # передача вектора пар
4×3 DataFrame
 Row │ a      b_sum  c_sum
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      4      6
   2 │     2      2      8
   3 │     3      4     10
   4 │     4      2     12

julia> combine(gd) do sdf # удаление группы при возврате DataFrame()
          sdf.c[1] != 1 ? sdf : DataFrame()
       end
6×3 DataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     2      1      2
   2 │     2      1      6
   3 │     3      2      3
   4 │     3      2      7
   5 │     4      1      4
   6 │     4      1      8

автоматическое разделение, переименование и сохранение ключей

julia> df = DataFrame(a=repeat([1, 2, 3, 4], outer=[2]),
                      b=repeat([2, 1], outer=[4]),
                      c=1:8);

julia> gd = groupby(df, :a);

julia> combine(gd, :b => :b1, :c => :c1, [:b, :c] => +, keepkeys=false)
8×3 DataFrame
 Row │ b1     c1     b_c_+
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     2      1      3
   2 │     2      5      7
   3 │     1      2      3
   4 │     1      6      7
   5 │     2      3      5
   6 │     2      7      9
   7 │     1      4      5
   8 │     1      8      9

трансляция и расширение столбцов

julia> df = DataFrame(a=repeat([1, 2, 3, 4], outer=[2]),
                      b=repeat([2, 1], outer=[4]),
                      c=1:8);

julia> gd = groupby(df, :a);

julia> combine(gd, :b, AsTable([:b, :c]) => ByRow(extrema) => [:min, :max])
8×4 DataFrame
 Row │ a      b      min    max
     │ Int64  Int64  Int64  Int64
─────┼────────────────────────────
   1 │     1      2      1      2
   2 │     1      2      2      5
   3 │     2      1      1      2
   4 │     2      1      1      6
   5 │     3      2      2      3
   6 │     3      2      2      7
   7 │     4      1      1      4
   8 │     4      1      1      8

julia> combine(gd, [:b, :c] .=> Ref) # предотвращение распределения вектора по нескольким строкам
4×3 DataFrame
 Row │ a      b_Ref      c_Ref
     │ Int64  SubArray…  SubArray…
─────┼─────────────────────────────
   1 │     1  [2, 2]     [1, 5]
   2 │     2  [1, 1]     [2, 6]
   3 │     3  [2, 2]     [3, 7]
   4 │     4  [1, 1]     [4, 8]

julia> combine(gd, AsTable(Not(:a)) => Ref) # защита результата
4×2 DataFrame
 Row │ a      b_c_Ref
     │ Int64  NamedTup…
─────┼─────────────────────────────────
   1 │     1  (b = [2, 2], c = [1, 5])
   2 │     2  (b = [1, 1], c = [2, 6])
   3 │     3  (b = [2, 2], c = [3, 7])
   4 │     4  (b = [1, 1], c = [4, 8])

julia> combine(gd, :, AsTable(Not(:a)) => sum, renamecols=false)
8×4 DataFrame
 Row │ a      b      c      b_c
     │ Int64  Int64  Int64  Int64
─────┼────────────────────────────
   1 │     1      2      1      3
   2 │     1      2      5      7
   3 │     2      1      2      3
   4 │     2      1      6      7
   5 │     3      2      3      5
   6 │     3      2      7      9
   7 │     4      1      4      5
   8 │     4      1      8      9

# DataFrames.fillcombinationsFunction

fillcombinations(df::AbstractDataFrame, indexcols;
                     allowduplicates::Bool=false,
                     fill=missing)

Создает все сочетания уровней столбцов indexcols во фрейме данных df. Уровни и их порядок определяются функцией levels (т. е. уникальные значения, отсортированные лексикографически по умолчанию, или пользовательский набор уровней для, например, столбцов CategoricalArray) в дополнение к отсутствующим (missing), если они есть.

Для сочетаний indexcols, отсутствующих в df, эти столбцы заполняются значением fill (missing по умолчанию).

Если allowduplicates=false (по умолчанию), indexcols могут содержать только уникальные сочетания значений indexcols. Если allowduplicates=true допускается использование дубликатов.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Примеры

julia> df = DataFrame(x=1:2, y='a':'b', z=["x", "y"])
2×3 DataFrame
 Row │ x      y     z
     │ Int64  Char  String
─────┼─────────────────────
   1 │     1  a     x
   2 │     2  b     y

julia> fillcombinations(df, [:x, :y])
4×3 DataFrame
 Row │ x      y     z
     │ Int64  Char  String?
─────┼──────────────────────
   1 │     1  a     x
   2 │     2  a     missing
   3 │     1  b     missing
   4 │     2  b     y

julia> fillcombinations(df, [:y, :z], fill=0)
4×3 DataFrame
 Row │ x       y     z
     │ Int64?  Char  String
─────┼──────────────────────
   1 │      1  a     x
   2 │      0  b     x
   3 │      0  a     y
   4 │      2  b     y

# DataFrames.flattenFunction

flatten(df::AbstractDataFrame, cols; scalar::Type=Union{})

Если столбцы cols фрейма данных df имеют итерируемые элементы, которые определяют length (например, вектор (Vector) векторов (Vector)), возвращается DataFrame, где каждый элемент каждого col в cols сглажен, означая, что столбец, соответствующий col, становится более длинным вектором, в котором исходные записи конкатенированы. Элементы строки i для df в столбцах, отличных от cols, будут повторяться в соответствии с длиной df[i, col]. Поэтому эти длины должны быть одинаковыми для каждого col в cols, иначе возникнет ошибка. Обратите внимание, что эти элементы не копируются, поэтому если они являются изменяемыми, их изменение в возвращаемом DataFrame повлияет на df.

cols может представлять собой любой селектор столбцов (символ (Symbol), строку или целое число; :, Cols, All, Between, Not, регулярное выражение или вектор символов (Symbol), строк или целых чисел).

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

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Примеры

julia> df1 = DataFrame(a=[1, 2], b=[[1, 2], [3, 4]], c=[[5, 6], [7, 8]])
2×3 DataFrame
 Row │ a      b       c
     │ Int64  Array…  Array…
─────┼───────────────────────
   1 │     1  [1, 2]  [5, 6]
   2 │     2  [3, 4]  [7, 8]

julia> flatten(df1, :b)
4×3 DataFrame
 Row │ a      b      c
     │ Int64  Int64  Array…
─────┼──────────────────────
   1 │     1      1  [5, 6]
   2 │     1      2  [5, 6]
   3 │     2      3  [7, 8]
   4 │     2      4  [7, 8]

julia> flatten(df1, [:b, :c])
4×3 DataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      1      5
   2 │     1      2      6
   3 │     2      3      7
   4 │     2      4      8

julia> df2 = DataFrame(a=[1, 2], b=[("p", "q"), ("r", "s")])
2×2 DataFrame
 Row │ a      b
     │ Int64  Tuple…
─────┼───────────────────
   1 │     1  ("p", "q")
   2 │     2  ("r", "s")

julia> flatten(df2, :b)
4×2 DataFrame
 Row │ a      b
     │ Int64  String
─────┼───────────────
   1 │     1  p
   2 │     1  q
   3 │     2  r
   4 │     2  s

julia> df3 = DataFrame(a=[1, 2], b=[[1, 2], [3, 4]], c=[[5, 6], [7]])
2×3 DataFrame
 Row │ a      b       c
     │ Int64  Array…  Array…
─────┼───────────────────────
   1 │     1  [1, 2]  [5, 6]
   2 │     2  [3, 4]  [7]

julia> flatten(df3, [:b, :c])
ERROR: ArgumentError: Lengths of iterables stored in columns :b and :c are not the same in row 2

julia> df4 = DataFrame(a=[1, 2, 3],
                       b=[[1, 2], missing, missing],
                       c=[[5, 6], missing, [7, 8]])
3×3 DataFrame
 Row │ a      b        c
     │ Int64  Array…?  Array…?
─────┼─────────────────────────
   1 │     1  [1, 2]   [5, 6]
   2 │     2  missing  missing
   3 │     3  missing  [7, 8]

julia> flatten(df4, [:b, :c], scalar=Missing)
5×3 DataFrame
 Row │ a      b        c
     │ Int64  Int64?   Int64?
─────┼─────────────────────────
   1 │     1        1        5
   2 │     1        2        6
   3 │     2  missing  missing
   4 │     3  missing        7
   5 │     3  missing        8

# Base.hcatFunction

hcat(df::AbstractDataFrame...;
     makeunique::Bool=false, copycols::Bool=true)

Выполняет горизонтальную конкатенацию фреймов данных.

Если makeunique=false (по умолчанию), имена столбцов передаваемых объектов должны быть уникальными. Если makeunique=true, к повторяющимся именам столбцов добавляется суффикс _i (i, начиная с 1 для первого повторяющегося имени).

Если copycols=true (по умолчанию), DataFrame, возвращаемый hcat, будет содержать скопированные столбцы из исходных фреймов данных. Если copycols=false, он будет содержать столбцы в том виде, в каком они хранятся в исходном фрейме данных (без копирования). Этот параметр следует использовать с осторожностью, так как изменение столбцов в исходных или возвращаемых DataFrame может привести к повреждению другого объекта.

Метаданные: функция hcat распространяет метаданные на уровне таблиц в стиле :note для ключей, присутствующих во всех передаваемых фреймах данных и имеющих одинаковое значение. Она распространяет метаданные на уровне столбцов в стиле :note.

Пример

julia> df1 = DataFrame(A=1:3, B=1:3)
3×2 DataFrame
 Row │ A      B
     │ Int64  Int64
─────┼──────────────
   1 │     1      1
   2 │     2      2
   3 │     3      3

julia> df2 = DataFrame(A=4:6, B=4:6)
3×2 DataFrame
 Row │ A      B
     │ Int64  Int64
─────┼──────────────
   1 │     4      4
   2 │     5      5
   3 │     6      6

julia> df3 = hcat(df1, df2, makeunique=true)
3×4 DataFrame
 Row │ A      B      A_1    B_1
     │ Int64  Int64  Int64  Int64
─────┼────────────────────────────
   1 │     1      1      4      4
   2 │     2      2      5      5
   3 │     3      3      6      6

julia> df3.A === df1.A
false

julia> df3 = hcat(df1, df2, makeunique=true, copycols=false);

julia> df3.A === df1.A
true

# Base.insert!Function

insert!(df::DataFrame, index::Integer, row::Union{Tuple, AbstractArray}; promote::Bool=false)
insert!(df::DataFrame, index::Integer, row::Union{DataFrameRow, NamedTuple,
                                                  AbstractDict, Tables.AbstractRow};
        cols::Symbol=:setequal, promote::Bool=(cols in [:union, :subset]))

Добавляет одну строку в df в позиции index на месте, принимая значения из row. index должен быть целым числом от 1 до nrow(df)+1.

Типы столбцов df сохраняются, а новые значения при необходимости преобразуются. При сбое преобразования возникает ошибка.

Если row не является ни DataFrameRow, ни NamedTuple, ни AbstractDict, она должна быть Tuple или AbstractArray, и столбцы сопоставляются в порядке появления. В этом случае row должна содержать столько же элементов, сколько столбцов в df.

Если строка (row) является DataFrameRow, NamedTuple, AbstractDict или Tables.AbstractRow, значения в row сопоставляются со столбцами в df на основе имен. Точное поведение зависит от значения аргумента cols, а именно:

  • Если cols == :setequal (по умолчанию), row должна содержать те же столбцы, что и df (но, возможно, в другом порядке).

  • Если cols == :orderequal, row должна содержать те же столбцы в том же порядке (для AbstractDict этот параметр требует, чтобы keys(row) совпадал с propertynames(df) в целях поддержки упорядоченных словарей. Однако если row является словарем (Dict), возникает ошибка, так как это неупорядоченная коллекция).

  • Если cols == :intersect, row должна содержать больше столбцов, чем df, но все имена столбцов, имеющиеся в df, должны присутствовать и в row, и только они используются для заполнения новой строки в df.

  • Если cols == :subset, действует как для :intersect, но если какой-то столбец отсутствует в row, отсутствующее (missing) значение отправляется в df.

  • Если cols == :union, столбцы, отсутствующие в df, которые присутствуют в row, добавляются в df (с использованием missing для существующих строк), и значение missing отправляется в столбцы, отсутствующие в row, которые присутствуют в df.

Если promote=true и тип элемента столбца, присутствующего в df, запрещает использовать тип отправляемого элемента, новый столбец с продвинутым типом элемента, разрешающим этот тип, выделяется заново и сохраняется в df. Если promote=false, возникает ошибка .

В отдельном случае, если df не имеет столбцов и row является NamedTuple, DataFrameRow, или Tables.AbstractRow, столбцы создаются для всех значений в row с использованием их имен и порядка.

Обратите внимание, что эта функция не должна использоваться для DataFrame, содержащего столбцы, которые являются псевдонимами (одинаковыми при сравнении ===).

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

См. также описание push!, pushfirst!

Примеры

julia> df = DataFrame(A='a':'c', B=1:3)
3×2 DataFrame
 Row │ A     B
     │ Char  Int64
─────┼─────────────
   1 │ a         1
   2 │ b         2
   3 │ c         3

julia> insert!(df, 2, (true, false), promote=true)
4×2 DataFrame
 Row │ A     B
     │ Any   Int64
─────┼─────────────
   1 │ a         1
   2 │ true      0
   3 │ b         2
   4 │ c         3

julia> insert!(df, 5, df[1, :])
5×2 DataFrame
 Row │ A     B
     │ Any   Int64
─────┼─────────────
   1 │ a         1
   2 │ true      0
   3 │ b         2
   4 │ c         3
   5 │ a         1

julia> insert!(df, 1, (C="something", A=11, B=12), cols=:intersect)
6×2 DataFrame
 Row │ A     B
     │ Any   Int64
─────┼─────────────
   1 │ 11       12
   2 │ a         1
   3 │ true      0
   4 │ b         2
   5 │ c         3
   6 │ a         1

julia> insert!(df, 7, Dict(:A=>1.0, :C=>1.0), cols=:union)
7×3 DataFrame
 Row │ A     B        C
     │ Any   Int64?   Float64?
─────┼──────────────────────────
   1 │ 11         12  missing
   2 │ a           1  missing
   3 │ true        0  missing
   4 │ b           2  missing
   5 │ c           3  missing
   6 │ a           1  missing
   7 │ 1.0   missing        1.0

julia> insert!(df, 3, NamedTuple(), cols=:subset)
8×3 DataFrame
 Row │ A        B        C
     │ Any      Int64?   Float64?
─────┼─────────────────────────────
   1 │ 11            12  missing
   2 │ a              1  missing
   3 │ missing  missing  missing
   4 │ true           0  missing
   5 │ b              2  missing
   6 │ c              3  missing
   7 │ a              1  missing
   8 │ 1.0      missing        1.0

# DataFrames.insertcolsFunction

insertcols(df::AbstractDataFrame[, col], (name=>val)::Pair...;
           after::Bool=false, makeunique::Bool=false, copycols::Bool=true)

Вставляет столбец в копию фрейма данных df с помощью функции insertcols! и возвращает созданный фрейм данных.

Если col не указан, он задается как ncol(df)+1 (столбец вставляется как последний столбец).

Аргументы

  • df: фрейм данных, в который будут добавлены столбцы.

  • col: позиция, в которую будет вставлен столбец, переданная как целое число, или имя столбца (строка или Symbol); столбец, выбранный с помощью col, и следующие за ним столбцы сдвигаются вправо в df после операции.

  • name: имя нового столбца.

  • val: AbstractVector, задающий содержимое нового столбца, или значение любого типа, отличного от AbstractArray, которое будет повторяться для заполнения нового вектора. Как правило, значения, хранящиеся в Ref или 0-мерном массиве AbstractArray, остаются без оболочки и обрабатываются одинаково.

  • after: если true, столбцы вставляются после col.

  • makeunique: определяет, что делать, если name уже существует в df. Если имеет значение false, возникает ошибка. Если имеет значение true, будет создано уникальное имя путем добавления суффикса.

  • copycols: должны ли копироваться векторы, переданные как столбцы.

Если val — это AbstractRange, вставляется результат collect(val).

Если df — это SubDataFrame, он должен быть создан с использованием : в качестве селектора столбцов (в противном случае возникнет ошибка). В этом случае именованный аргумент copycols игнорируется (т. е. добавленный столбец всегда копируется), и столбец родительского фрейма данных заполняется отсутствующими (missing) строками, отфильтрованными с помощью df.

Если df — это DataFrame, в котором нет столбцов, и передаются только значения, отличные от AbstractVector, он используется для создания одноэлементного столбца. Если df — это DataFrame, в котором нет столбцов, и передается как минимум один AbstractVector, его длина используется для определения количества элементов во всех созданных столбцах. Во всех других случаях количество строк во всех созданных столбцах должно соответствовать nrow(df).

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

См. также описание insertcols!.

Примеры

julia> df = DataFrame(a=1:3)
3×1 DataFrame
 Row │ a
     │ Int64
─────┼───────
   1 │     1
   2 │     2
   3 │     3

julia> insertcols(df, 1, :b => 'a':'c')
3×2 DataFrame
 Row │ b     a
     │ Char  Int64
─────┼─────────────
   1 │ a         1
   2 │ b         2
   3 │ c         3

julia> insertcols(df, :c => 2:4, :c => 3:5, makeunique=true)
3×3 DataFrame
 Row │ a      c      c_1
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      2      3
   2 │     2      3      4
   3 │     3      4      5

julia> insertcols(df, :a, :d => 7:9, after=true)
3×2 DataFrame
 Row │ a      d
     │ Int64  Int64
─────┼──────────────
   1 │     1      7
   2 │     2      8
   3 │     3      9

# DataFrames.insertcols!Function

insertcols!(df::AbstractDataFrame[, col], (name=>val)::Pair...;
            after::Bool=false, makeunique::Bool=false, copycols::Bool=true)

Вставляет столбец во фрейм данных на месте. Возвращает обновленный фрейм данных.

Если col не указан, он задается как ncol(df)+1 (столбец вставляется как последний столбец).

Аргументы

  • df: фрейм данных, в который будут добавлены столбцы.

  • col: позиция, в которую будет вставлен столбец, переданная как целое число, или имя столбца (строка или Symbol); столбец, выбранный с помощью col, и следующие за ним столбцы сдвигаются вправо в df после операции.

  • name: имя нового столбца.

  • val: AbstractVector, задающий содержимое нового столбца, или значение любого типа, отличного от AbstractArray, которое будет повторяться для заполнения нового вектора. Как правило, значения, хранящиеся в Ref или 0-мерном массиве AbstractArray, остаются без оболочки и обрабатываются одинаково.

  • after: если true, столбцы вставляются после col.

  • makeunique: определяет, что делать, если name уже существует в df. Если имеет значение false, возникает ошибка. Если имеет значение true, будет создано уникальное имя путем добавления суффикса.

  • copycols: должны ли копироваться векторы, переданные как столбцы.

Если val — это AbstractRange, вставляется результат collect(val).

Если df — это SubDataFrame, он должен быть создан с использованием : в качестве селектора столбцов (в противном случае возникнет ошибка). В этом случае именованный аргумент copycols игнорируется (т. е. добавленный столбец всегда копируется), и столбец родительского фрейма данных заполняется отсутствующими (missing) строками, отфильтрованными с помощью df.

Если df — это DataFrame, в котором нет столбцов, и передаются только значения, отличные от AbstractVector, он используется для создания одноэлементного столбца. Если df — это DataFrame, в котором нет столбцов, и передается как минимум один AbstractVector, его длина используется для определения количества элементов во всех созданных столбцах. Во всех других случаях количество строк во всех созданных столбцах должно соответствовать nrow(df).

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Метаданные, имеющие другие стили, удаляются (из родительского фрейма данных, если df является SubDataFrame).

См. также описание insertcols.

Примеры

julia> df = DataFrame(a=1:3)
3×1 DataFrame
 Row │ a
     │ Int64
─────┼───────
   1 │     1
   2 │     2
   3 │     3

julia> insertcols!(df, 1, :b => 'a':'c')
3×2 DataFrame
 Row │ b     a
     │ Char  Int64
─────┼─────────────
   1 │ a         1
   2 │ b         2
   3 │ c         3

julia> insertcols!(df, 2, :c => 2:4, :c => 3:5, makeunique=true)
3×4 DataFrame
 Row │ b     c      c_1    a
     │ Char  Int64  Int64  Int64
─────┼───────────────────────────
   1 │ a         2      3      1
   2 │ b         3      4      2
   3 │ c         4      5      3

julia> insertcols!(df, :b, :d => 7:9, after=true)
3×5 DataFrame
 Row │ b     d      c      c_1    a
     │ Char  Int64  Int64  Int64  Int64
─────┼──────────────────────────────────
   1 │ a         7      2      3      1
   2 │ b         8      3      4      2
   3 │ c         9      4      5      3

# Base.invpermute!Function

invpermute!(df::AbstractDataFrame, p)

Аналогична permute!, но применяется перестановка, обратная заданной.

invpermute! выдаст корректный результат, даже если некоторые столбцы переданного фрейма данных или перестановки p идентичны (проверены с помощью ===). В противном случае, если два столбца имеют общую часть памяти, но не идентичны (например, являются разными представлениями одного и того же родительского вектора), результат invpermute! может быть неверным.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Метаданные, имеющие другие стили, удаляются (из родительского фрейма данных, если df является SubDataFrame).

Примеры

julia> df = DataFrame(a=1:5, b=6:10, c=11:15)
5×3 DataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      6     11
   2 │     2      7     12
   3 │     3      8     13
   4 │     4      9     14
   5 │     5     10     15

julia> permute!(df, [5, 3, 1, 2, 4])
5×3 DataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     5     10     15
   2 │     3      8     13
   3 │     1      6     11
   4 │     2      7     12
   5 │     4      9     14

julia> invpermute!(df, [5, 3, 1, 2, 4])
5×3 DataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      6     11
   2 │     2      7     12
   3 │     3      8     13
   4 │     4      9     14
   5 │     5     10     15

# DataFrames.mapcolsFunction

mapcols(f::Union{Function, Type}, df::AbstractDataFrame)

Возвращает DataFrame, в котором каждый столбец df преобразуется с помощью функции f. Функция f должна возвращать объекты AbstractVector с одинаковой длиной или скаляры (скалярами считаются все значения, отличные от AbstractVector).

Обратите внимание, что mapcols гарантирует, что столбцы из df не будут повторно использоваться в возвращаемом DataFrame. Если f возвращает аргумент, он копируется перед сохранением.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Примеры

julia> df = DataFrame(x=1:4, y=11:14)
4×2 DataFrame
 Row │ x      y
     │ Int64  Int64
─────┼──────────────
   1 │     1     11
   2 │     2     12
   3 │     3     13
   4 │     4     14

julia> mapcols(x -> x.^2, df)
4×2 DataFrame
 Row │ x      y
     │ Int64  Int64
─────┼──────────────
   1 │     1    121
   2 │     4    144
   3 │     9    169
   4 │    16    196

# DataFrames.mapcols!Function

mapcols!(f::Union{Function, Type}, df::DataFrame)

Обновляет DataFrame на месте, где каждый столбец df преобразуется с помощью функции f. Функция f должна возвращать объекты AbstractVector с одинаковой длиной или скаляры (скалярами считаются все значения, отличные от AbstractVector).

Обратите внимание, что mapcols! повторно использует столбцы из df, если они возвращены функцией f.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Примеры

julia> df = DataFrame(x=1:4, y=11:14)
4×2 DataFrame
 Row │ x      y
     │ Int64  Int64
─────┼──────────────
   1 │     1     11
   2 │     2     12
   3 │     3     13
   4 │     4     14

julia> mapcols!(x -> x.^2, df);

julia> df
4×2 DataFrame
 Row │ x      y
     │ Int64  Int64
─────┼──────────────
   1 │     1    121
   2 │     4    144
   3 │     9    169
   4 │    16    196

# Base.permute!Function

permute!(df::AbstractDataFrame, p)

Перестанавливает фрейм данных df на месте в соответствии с перестановкой p. Если p не является перестановкой, возникает ошибка ArgumentError.

Чтобы возвратить новый фрейм данных вместо перестановки df на месте, используйте df[p, :].

permute! выдаст корректный результат, даже если некоторые столбцы переданного фрейма данных или перестановки p идентичны (проверены с помощью ===). В противном случае, если два столбца имеют общую часть памяти, но не идентичны (например, являются разными представлениями одного и того же родительского вектора), результат permute! может быть неверным.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Метаданные, имеющие другие стили, удаляются (из родительского фрейма данных, если df является SubDataFrame).

Примеры

julia> df = DataFrame(a=1:5, b=6:10, c=11:15)
5×3 DataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      6     11
   2 │     2      7     12
   3 │     3      8     13
   4 │     4      9     14
   5 │     5     10     15

julia> permute!(df, [5, 3, 1, 2, 4])
5×3 DataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     5     10     15
   2 │     3      8     13
   3 │     1      6     11
   4 │     2      7     12
   5 │     4      9     14

# Base.prepend!Function

prepend!(df::DataFrame, df2::AbstractDataFrame; cols::Symbol=:setequal,
         promote::Bool=(cols in [:union, :subset]))
prepend!(df::DataFrame, table; cols::Symbol=:setequal,
         promote::Bool=(cols in [:union, :subset]))

Add the rows of df2 to the beginning of df. If the second argument table is not an AbstractDataFrame then it is converted using DataFrame(table, copycols=false) before being prepended.

The exact behavior of prepend! depends on the cols argument:

  • If cols == :setequal (this is the default) then df2 must contain exactly the same columns as df (but possibly in a different order).

  • If cols == :orderequal then df2 must contain the same columns in the same order (for AbstractDict this option requires that keys(row) matches propertynames(df) to allow for support of ordered dicts; however, if df2 is a Dict an error is thrown as it is an unordered collection).

  • If cols == :intersect then df2 may contain more columns than df, but all column names that are present in df must be present in df2 and only these are used.

  • If cols == :subset then append! behaves like for :intersect but if some column is missing in df2 then a missing value is pushed to df.

  • If cols == :union then append! adds columns missing in df that are present in df2, for columns present in df but missing in df2 a missing value is pushed.

If promote=true and element type of a column present in df does not allow the type of a pushed argument then a new column with a promoted element type allowing it is freshly allocated and stored in df. If promote=false an error is thrown.

The above rule has the following exceptions:

  • If df has no columns then copies of columns from df2 are added to it.

  • If df2 has no columns then calling prepend! leaves df unchanged.

Please note that prepend! must not be used on a DataFrame that contains columns that are aliases (equal when compared with ===).

Metadata: table-level :note-style metadata and column-level :note-style metadata for columns present in df are preserved. If new columns are added their :note-style metadata is copied from the appended table. Other metadata is dropped.

See also: use pushfirst! to add individual rows at the beginning of a data frame, append! to add a table at the end, and vcat to vertically concatenate data frames.

Examples

julia> df1 = DataFrame(A=1:3, B=1:3)
3×2 DataFrame
 Row │ A      B
     │ Int64  Int64
─────┼──────────────
   1 │     1      1
   2 │     2      2
   3 │     3      3

julia> df2 = DataFrame(A=4.0:6.0, B=4:6)
3×2 DataFrame
 Row │ A        B
     │ Float64  Int64
─────┼────────────────
   1 │     4.0      4
   2 │     5.0      5
   3 │     6.0      6

julia> prepend!(df1, df2);

julia> df1
6×2 DataFrame
 Row │ A      B
     │ Int64  Int64
─────┼──────────────
   1 │     4      4
   2 │     5      5
   3 │     6      6
   4 │     1      1
   5 │     2      2
   6 │     3      3

# Base.push!Function

push!(df::DataFrame, row::Union{Tuple, AbstractArray}; promote::Bool=false)
push!(df::DataFrame, row::Union{DataFrameRow, NamedTuple, AbstractDict,
                                Tables.AbstractRow};
      cols::Symbol=:setequal, promote::Bool=(cols in [:union, :subset]))

Add one row at the end of df in-place, taking the values from row.

Column types of df are preserved, and new values are converted if necessary. An error is thrown if conversion fails.

If row is neither a DataFrameRow, NamedTuple nor AbstractDict then it must be a Tuple or an AbstractArray and columns are matched by order of appearance. In this case row must contain the same number of elements as the number of columns in df.

If row is a DataFrameRow, NamedTuple, AbstractDict, or Tables.AbstractRow then values in row are matched to columns in df based on names. The exact behavior depends on the cols argument value in the following way:

  • If cols == :setequal (this is the default) then row must contain exactly the same columns as df (but possibly in a different order).

  • If cols == :orderequal then row must contain the same columns in the same order (for AbstractDict this option requires that keys(row) matches propertynames(df) to allow for support of ordered dicts; however, if row is a Dict an error is thrown as it is an unordered collection).

  • If cols == :intersect then row may contain more columns than df, but all column names that are present in df must be present in row and only they are used to populate a new row in df.

  • If cols == :subset then the behavior is like for :intersect but if some column is missing in row then a missing value is pushed to df.

  • If cols == :union then columns missing in df that are present in row are added to df (using missing for existing rows) and a missing value is pushed to columns missing in row that are present in df.

If promote=true and element type of a column present in df does not allow the type of a pushed argument then a new column with a promoted element type allowing it is freshly allocated and stored in df. If promote=false an error is thrown.

As a special case, if df has no columns and row is a NamedTuple, DataFrameRow, or Tables.AbstractRow, columns are created for all values in row, using their names and order.

Please note that this function must not be used on a DataFrame that contains columns that are aliases (equal when compared with ===).

Metadata: this function preserves table-level and column-level :note-style metadata.

See also: pushfirst!, insert!

Examples

julia> df = DataFrame(A='a':'c', B=1:3)
3×2 DataFrame
 Row │ A     B
     │ Char  Int64
─────┼─────────────
   1 │ a         1
   2 │ b         2
   3 │ c         3

julia> push!(df, (true, false), promote=true)
4×2 DataFrame
 Row │ A     B
     │ Any   Int64
─────┼─────────────
   1 │ a         1
   2 │ b         2
   3 │ c         3
   4 │ true      0

julia> push!(df, df[1, :])
5×2 DataFrame
 Row │ A     B
     │ Any   Int64
─────┼─────────────
   1 │ a         1
   2 │ b         2
   3 │ c         3
   4 │ true      0
   5 │ a         1

julia> push!(df, (C="something", A=11, B=12), cols=:intersect)
6×2 DataFrame
 Row │ A     B
     │ Any   Int64
─────┼─────────────
   1 │ a         1
   2 │ b         2
   3 │ c         3
   4 │ true      0
   5 │ a         1
   6 │ 11       12

julia> push!(df, Dict(:A=>1.0, :C=>1.0), cols=:union)
7×3 DataFrame
 Row │ A     B        C
     │ Any   Int64?   Float64?
─────┼──────────────────────────
   1 │ a           1  missing
   2 │ b           2  missing
   3 │ c           3  missing
   4 │ true        0  missing
   5 │ a           1  missing
   6 │ 11         12  missing
   7 │ 1.0   missing        1.0

julia> push!(df, NamedTuple(), cols=:subset)
8×3 DataFrame
 Row │ A        B        C
     │ Any      Int64?   Float64?
─────┼─────────────────────────────
   1 │ a              1  missing
   2 │ b              2  missing
   3 │ c              3  missing
   4 │ true           0  missing
   5 │ a              1  missing
   6 │ 11            12  missing
   7 │ 1.0      missing        1.0
   8 │ missing  missing  missing

# Base.pushfirst!Function

pushfirst!(df::DataFrame, row::Union{Tuple, AbstractArray}; promote::Bool=false)
pushfirst!(df::DataFrame, row::Union{DataFrameRow, NamedTuple, AbstractDict,
                                     Tables.AbstractRow};
           cols::Symbol=:setequal, promote::Bool=(cols in [:union, :subset]))

Добавляет одну строку в начало df на месте, принимая значения из row.

Типы столбцов df сохраняются, а новые значения при необходимости преобразуются. При сбое преобразования возникает ошибка.

Если row не является ни DataFrameRow, ни NamedTuple, ни AbstractDict, она должна быть Tuple или AbstractArray, и столбцы сопоставляются в порядке появления. В этом случае row должна содержать столько же элементов, сколько столбцов в df.

Если строка (row) является DataFrameRow, NamedTuple, AbstractDict или Tables.AbstractRow, значения в row сопоставляются со столбцами в df на основе имен. Точное поведение зависит от значения аргумента cols, а именно:

  • Если cols == :setequal (по умолчанию), row должна содержать те же столбцы, что и df (но, возможно, в другом порядке).

  • Если cols == :orderequal, row должна содержать те же столбцы в том же порядке (для AbstractDict этот параметр требует, чтобы keys(row) совпадал с propertynames(df) в целях поддержки упорядоченных словарей. Однако если row является словарем (Dict), возникает ошибка, так как это неупорядоченная коллекция).

  • Если cols == :intersect, row должна содержать больше столбцов, чем df, но все имена столбцов, имеющиеся в df, должны присутствовать и в row, и только они используются для заполнения новой строки в df.

  • Если cols == :subset, действует как для :intersect, но если какой-то столбец отсутствует в row, отсутствующее (missing) значение отправляется в df.

  • Если cols == :union, столбцы, отсутствующие в df, которые присутствуют в row, добавляются в df (с использованием missing для существующих строк), и значение missing отправляется в столбцы, отсутствующие в row, которые присутствуют в df.

Если promote=true и тип элемента столбца, присутствующего в df, запрещает использовать тип отправляемого элемента, новый столбец с продвинутым типом элемента, разрешающим этот тип, выделяется заново и сохраняется в df. Если promote=false, возникает ошибка .

В отдельном случае, если df не имеет столбцов и row является NamedTuple, DataFrameRow, или Tables.AbstractRow, столбцы создаются для всех значений в row с использованием их имен и порядка.

Обратите внимание, что эта функция не должна использоваться для DataFrame, содержащего столбцы, которые являются псевдонимами (одинаковыми при сравнении ===).

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

См. также описание push!, insert!.

Примеры

julia> df = DataFrame(A='a':'c', B=1:3)
3×2 DataFrame
 Row │ A     B
     │ Char  Int64
─────┼─────────────
   1 │ a         1
   2 │ b         2
   3 │ c         3

julia> pushfirst!(df, (true, false), promote=true)
4×2 DataFrame
 Row │ A     B
     │ Any   Int64
─────┼─────────────
   1 │ true      0
   2 │ a         1
   3 │ b         2
   4 │ c         3

julia> pushfirst!(df, df[1, :])
5×2 DataFrame
 Row │ A     B
     │ Any   Int64
─────┼─────────────
   1 │ true      0
   2 │ true      0
   3 │ a         1
   4 │ b         2
   5 │ c         3

julia> pushfirst!(df, (C="something", A=11, B=12), cols=:intersect)
6×2 DataFrame
 Row │ A     B
     │ Any   Int64
─────┼─────────────
   1 │ 11       12
   2 │ true      0
   3 │ true      0
   4 │ a         1
   5 │ b         2
   6 │ c         3

julia> pushfirst!(df, Dict(:A=>1.0, :C=>1.0), cols=:union)
7×3 DataFrame
 Row │ A     B        C
     │ Any   Int64?   Float64?
─────┼──────────────────────────
   1 │ 1.0   missing        1.0
   2 │ 11         12  missing
   3 │ true        0  missing
   4 │ true        0  missing
   5 │ a           1  missing
   6 │ b           2  missing
   7 │ c           3  missing

julia> pushfirst!(df, NamedTuple(), cols=:subset)
8×3 DataFrame
 Row │ A        B        C
     │ Any      Int64?   Float64?
─────┼─────────────────────────────
   1 │ missing  missing  missing
   2 │ 1.0      missing        1.0
   3 │ 11            12  missing
   4 │ true           0  missing
   5 │ true           0  missing
   6 │ a              1  missing
   7 │ b              2  missing
   8 │ c              3  missing

# Base.reduceFunction

reduce(::typeof(vcat),
       dfs::Union{AbstractVector{<:AbstractDataFrame},
                  Tuple{AbstractDataFrame, Vararg{AbstractDataFrame}}};
       cols::Union{Symbol, AbstractVector{Symbol},
                   AbstractVector{<:AbstractString}}=:setequal,
       source::Union{Nothing, Symbol, AbstractString,
                     Pair{<:Union{Symbol, AbstractString}, <:AbstractVector}}=nothing,
       init::AbstractDataFrame=DataFrame())

Эффективно упрощает заданный вектор или кортеж AbstractDataFrame с помощью vcat.

См. docstring vcat с описанием именованных аргументов cols и source.

Именованный аргумент init представляет собой начальное значение для использования в упрощениях. Он должен быть фреймом данных без строк. Он не учитывается ни при вычислении значения исходного (source) столбца, ни при определении метаданных создаваемого фрейма данных.

Порядок, имена и типы столбцов результирующего DataFrame, а также поведение именованных аргументов cols и source следуют правилам, указанным для vcat фреймов AbstractDataFrame.

Метаданные: функция vcat распространяет метаданные на уровне таблиц в стиле :note для ключей, присутствующих во всех передаваемых фреймах данных и имеющих одинаковое значение. Функция vcat распространяет метаданные на уровне столбцов в стиле :note для ключей, присутствующих во всех передаваемых фреймах данных, содержащих этот столбец, и имеющих одинаковое значение.

Пример

julia> df1 = DataFrame(A=1:3, B=1:3)
3×2 DataFrame
 Row │ A      B
     │ Int64  Int64
─────┼──────────────
   1 │     1      1
   2 │     2      2
   3 │     3      3

julia> df2 = DataFrame(A=4:6, B=4:6)
3×2 DataFrame
 Row │ A      B
     │ Int64  Int64
─────┼──────────────
   1 │     4      4
   2 │     5      5
   3 │     6      6

julia> df3 = DataFrame(A=7:9, C=7:9)
3×2 DataFrame
 Row │ A      C
     │ Int64  Int64
─────┼──────────────
   1 │     7      7
   2 │     8      8
   3 │     9      9

julia> reduce(vcat, (df1, df2))
6×2 DataFrame
 Row │ A      B
     │ Int64  Int64
─────┼──────────────
   1 │     1      1
   2 │     2      2
   3 │     3      3
   4 │     4      4
   5 │     5      5
   6 │     6      6

julia> reduce(vcat, [df1, df2, df3], cols=:union, source=:source)
9×4 DataFrame
 Row │ A      B        C        source
     │ Int64  Int64?   Int64?   Int64
─────┼─────────────────────────────────
   1 │     1        1  missing       1
   2 │     2        2  missing       1
   3 │     3        3  missing       1
   4 │     4        4  missing       2
   5 │     5        5  missing       2
   6 │     6        6  missing       2
   7 │     7  missing        7       3
   8 │     8  missing        8       3
   9 │     9  missing        9       3

# Base.repeatFunction

repeat(df::AbstractDataFrame; inner::Integer = 1, outer::Integer = 1)

Создает фрейм данных, повторяя строки в df. inner указывает количество повторений каждой строки, а outer указывает количество повторений полного набора строк.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Пример

julia> df = DataFrame(a=1:2, b=3:4)
2×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      3
   2 │     2      4

julia> repeat(df, inner=2, outer=3)
12×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      3
   2 │     1      3
   3 │     2      4
   4 │     2      4
   5 │     1      3
   6 │     1      3
   7 │     2      4
   8 │     2      4
   9 │     1      3
  10 │     1      3
  11 │     2      4
  12 │     2      4
repeat(df::AbstractDataFrame, count::Integer)

Создает фрейм данных, повторяя каждую строку в df столько раз, сколько указано с помощью count.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Пример

julia> df = DataFrame(a=1:2, b=3:4)
2×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      3
   2 │     2      4

julia> repeat(df, 2)
4×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      3
   2 │     2      4
   3 │     1      3
   4 │     2      4

# DataFrames.repeat!Function

repeat!(df::DataFrame; inner::Integer=1, outer::Integer=1)

Обновляет фрейм данных df на месте, повторяя его строки. inner указывает количество повторений каждой строки, а outer указывает количество повторений полного набора строк. Столбцы df являются только что выделенными.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Пример

julia> df = DataFrame(a=1:2, b=3:4)
2×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      3
   2 │     2      4

julia> repeat!(df, inner=2, outer=3);

julia> df
12×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      3
   2 │     1      3
   3 │     2      4
   4 │     2      4
   5 │     1      3
   6 │     1      3
   7 │     2      4
   8 │     2      4
   9 │     1      3
  10 │     1      3
  11 │     2      4
  12 │     2      4
repeat!(df::DataFrame, count::Integer)

Обновляет фрейм данных df на месте, повторяя его строки столько раз, сколько указано с помощью count. Столбцы df являются только что выделенными.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Пример

julia> df = DataFrame(a=1:2, b=3:4)
2×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      3
   2 │     2      4

julia> repeat(df, 2)
4×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      3
   2 │     2      4
   3 │     1      3
   4 │     2      4

# Base.reverseFunction

reverse(df::AbstractDataFrame, start=1, stop=nrow(df))

Return a data frame containing the rows in df in reversed order. If start and stop are provided, only rows in the start:stop range are affected.

Metadata: this function preserves table-level and column-level :note-style metadata.

Examples

julia> df = DataFrame(a=1:5, b=6:10, c=11:15)
5×3 DataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      6     11
   2 │     2      7     12
   3 │     3      8     13
   4 │     4      9     14
   5 │     5     10     15

julia> reverse(df)
5×3 DataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     5     10     15
   2 │     4      9     14
   3 │     3      8     13
   4 │     2      7     12
   5 │     1      6     11

julia> reverse(df, 2, 3)
5×3 DataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      6     11
   2 │     3      8     13
   3 │     2      7     12
   4 │     4      9     14
   5 │     5     10     15

# Base.reverse!Function

reverse!(df::AbstractDataFrame, start=1, stop=nrow(df))

Mutate data frame in-place to reverse its row order. If start and stop are provided, only rows in the start:stop range are affected.

reverse! will produce a correct result even if some columns of passed data frame are identical (checked with ===). Otherwise, if two columns share some part of memory but are not identical (e.g. are different views of the same parent vector) then reverse! result might be incorrect.

Metadata: this function preserves table-level and column-level :note-style metadata.

Metadata having other styles is dropped (from parent data frame when df is a SubDataFrame).

Examples

julia> df = DataFrame(a=1:5, b=6:10, c=11:15)
5×3 DataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      6     11
   2 │     2      7     12
   3 │     3      8     13
   4 │     4      9     14
   5 │     5     10     15

julia> reverse!(df)
5×3 DataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     5     10     15
   2 │     4      9     14
   3 │     3      8     13
   4 │     2      7     12
   5 │     1      6     11

julia> reverse!(df, 2, 3)
5×3 DataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     5     10     15
   2 │     3      8     13
   3 │     4      9     14
   4 │     2      7     12
   5 │     1      6     11

# DataFrames.selectFunction

select(df::AbstractDataFrame, args...;
       copycols::Bool=true, renamecols::Bool=true, threads::Bool=true)
select(args::Callable, df::DataFrame;
       renamecols::Bool=true, threads::Bool=true)
select(gd::GroupedDataFrame, args...;
       copycols::Bool=true, keepkeys::Bool=true, ungroup::Bool=true,
       renamecols::Bool=true, threads::Bool=true)
select(f::Base.Callable, gd::GroupedDataFrame;
       copycols::Bool=true, keepkeys::Bool=true, ungroup::Bool=true,
       renamecols::Bool=true, threads::Bool=true)

Создает новый фрейм данных, содержащий столбцы из df или gd, указанные с помощью args, и возвращает его. Результат гарантированно имеет то же количество строк, что и df, за исключением ситуаций, когда ни один столбец не выбран (в этом случае результат не содержит строк).

Ниже подробно описаны и сопоставлены общие правила для всех функций преобразования, поддерживаемых DataFrames.jl.

Все эти операции поддерживаются как для AbstractDataFrame (при пропуске шагов разделения и объединения), так и для GroupedDataFrame. Технически AbstractDataFrame считается сгруппированным без столбцов (это означает, что у него есть одна группа или ни одной, если он пуст). Единственное отличие заключается в том, что в этом случае именованные аргументы keepkeys и ungroup (описанные ниже) не поддерживаются, и всегда возвращается фрейм данных, поскольку в этом случае нет шагов разделения и объединения.

Чтобы выполнять операции с группами, сначала нужно создать объект GroupedDataFrame из фрейма данных с помощью функции groupby, которая принимает два аргумента: (1) фрейм данных, который нужно сгруппировать, и (2) набор столбцов, по которым осуществляется группировка.

Затем можно применить операции к каждой группе с помощью одной из следующих функций:

  • combine: не накладывает ограничений на количество возвращаемых строк в каждой группе; возвращаемые значения конкатенируются по вертикали в соответствии с порядком групп в GroupedDataFrame; обычно используется для вычисления сводной статистики по группам; для GroupedDataFrame, если группирующие столбцы сохраняются, они помещаются первыми в результат;

  • select: возвращает фрейм данных с количеством и порядком строк, точно таким же, как в исходном фрейме данных, включая только новые вычисленные столбцы; select! является версией на месте для select; для GroupedDataFrame, если группирующие столбцы сохраняются, они помещаются первыми в результат;

  • transform: возвращает фрейм данных с количеством и порядком строк, точно таким же, как в исходном фрейме данных, включая все столбцы из исходного фрейма и новые вычисленные столбцы; transform! является версией на месте для transform; существующие столбцы в исходном фрейме данных помещаются первыми в результат.

Особый случай: если передается GroupedDataFrame без групп, результат операции определяется путем выполнения одного вызова функции преобразования с переданным ей аргументом с нулем строк. Выходные данные этой операции используются только для определения количества и типа созданных столбцов, но результат не содержит строк.

Все эти функции принимают спецификацию одной или нескольких функций для применения к каждому подмножеству DataFrame. Эта спецификация может иметь следующий вид:

  1. Стандартные селекторы столбцов (целые числа, символы (Symbol), строки, векторы целых чисел, векторы символов (Symbol), векторы строк, All, Cols, :, Between, Not и регулярные выражения).

  2. Пара cols => function, указывающая, что функцию (function) следует вызывать с позиционными аргументами, содержащими столбцы cols, которые могут быть любым допустимым селектором столбцов. В этом случае имя целевого столбца генерируется автоматически и предполагается, что функция (function) возвращает единичное значение или вектор. Сгенерированное имя создается путем конкатенации имени исходного столбца и имени функции (function) по умолчанию (см. примеры ниже).

  3. Форма cols => function => target_cols, дополнительно явно указывающая целевой столбец или столбцы, которые должны быть одним именем (как Symbol или строка), вектором имен или AsTable. Кроме того, это может быть функция (Function), которая принимает в качестве аргумента строку или вектор строк, содержащие имена столбцов, выбранные с помощью cols, и возвращает имена целевых столбцов (допускаются все принятые типы, кроме AsTable).

  4. Пара col => target_cols, которая переименовывает столбец col в target_cols, который должен быть одним именем (как Symbol или строка), вектором имен или AsTable.

  5. Независимые от столбцов операции function => target_cols или просто function для конкретных функций (function), где входные столбцы опущены; без target_cols новый столбец имеет то же имя, что и function, в противном случае должен быть одним именем (как Symbol или строка). Поддерживаются следующие функции (function).

    • nrow для эффективного вычисления количества строк в каждой группе.

    • proprow для эффективного вычисления доли строк в каждой группе.

    • eachindex для возврата вектора, содержащего номер каждой строки в каждой группе.

    • groupindices для возврата номера группы.

  6. Векторы или матрицы, содержащие преобразования, заданные синтаксисом Pair, описываются в пунктах 2—​5.

  7. Функция, которая будет вызвана с SubDataFrame, соответствующим каждой группе, если обрабатывается GroupedDataFrame, или с самим фреймом данных, если обрабатывается AbstractDataFrame. Эту форму не рекомендуется использовать из-за ее низкой производительности, за исключением случаев, когда количество групп невелико или обрабатывается очень большое количество столбцов (в этом случае SubDataFrame позволяет избежать чрезмерной компиляции).

Примечание. Если передается выражение вида x => y, то, за исключением специального вспомогательного вида nrow => target_cols, оно всегда интерпретируется как cols => function. В частности, следующее выражение function => target_cols не является допустимой спецификацией преобразования.

Примечание. Если cols или target_cols являются All, Cols, Between или Not, поддерживается трансляция с использованием .=>, и она эквивалентна трансляции результата names(df, cols) или names(df, target_cols). Это работает, как будто трансляция произошла после замены селектора выбранными именами столбцов в области фрейма данных.

Все функции имеют два типа сигнатур. Один из них принимает GroupedDataFrame в качестве первого аргумента и произвольное количество преобразований, описанных выше, в качестве последующих аргументов. Второй тип сигнатуры — это когда в качестве первого аргумента передается Function или Type и GroupedDataFrame в качестве второго аргумента (аналогично map).

Есть особое правило: если при использовании синтаксисов cols => function и cols => function => target_cols cols заключен в объект AsTable, NamedTuple, содержащий столбцы, выбранные с помощью cols, передается function. Дополнительные сведения см. в документации по DataFrames.table_transformation, где также рассматриваются вопросы производительности.

Результат, который может возвращать функция (function), определяется значением target_cols.

  1. Если cols и target_cols опущены (передается только function), при возврате фрейма данных, матрицы, NamedTuple, Tables.AbstractRow или DataFrameRow будет создано несколько столбцов. При возврате любого другого значения создается один столбец.

  2. Если target_cols является символом (Symbol) или строкой, предполагается, что функция возвратит один столбец. В этом случае при возврате фрейма данных, матрицы, NamedTuple, Tables.AbstractRow или DataFrameRow возникнет ошибка.

  3. Если target_cols является вектором символов (Symbol) или строк или AsTable, предполагается, что функция (function) возвратит несколько столбцов. Если функция (function) возвращает какой-либо элемент из AbstractDataFrame, NamedTuple, DataFrameRow, Tables.AbstractRow, AbstractMatrix, применяется правило, описанное в пункте 1 выше. Если функция (function) возвращает AbstractVector, каждый элемент этого вектора должен поддерживать функцию keys, которая должна возвращать коллекцию Symbol, строк или целых чисел. Возвращаемое значение keys должно быть одинаковым для всех элементов. Затем создается столько столбцов, сколько элементов содержится в возвращаемом значении функции keys. Если target_cols является AsTable, их имена задаются равными именам ключей, за исключением случаев, когда keys возвращает целые числа, тогда они получают префикс x (таким образом, имена столбцов будут выглядеть как x1, x2 и т. д.). Если target_cols является вектором символов (Symbol) или строк, имена столбцов, созданные на основе приведенных выше правил, игнорируются и заменяются target_cols (в этом случае количество столбцов должно совпадать с длиной target_cols). Если fun возвращает значение любого другого типа, предполагается, что это таблица, соответствующая API Tables.jl, и для нее вызывается функция Tables.columntable для получения результирующих столбцов и их имен. Имена сохраняются, когда target_cols является AsTable, и заменяются, если target_cols является вектором символов (Symbol) или строк.

Во всех этих случаях функция (function) может возвращать как одну строку, так и несколько. Как правило, значения, заключенные в Ref или 0-мерный массив AbstractArray, распаковываются и после этого считаются одной строкой.

select/select! и transform/transform! всегда возвращают фрейм данных с количеством и порядком строк, точно таким же, как у исходного (даже если в GroupedDataFrame был изменен порядок групп), за исключением случаев, когда в результирующем фрейме данных нет столбцов (в этом случае результат не содержит строк).

Для combine строки в возвращаемом объекте отображаются в порядке групп в GroupedDataFrame. Функции могут возвращать произвольное количество строк для каждой группы, но тип возвращаемого объекта и количество и имена столбцов должны быть одинаковыми для всех групп, за исключением случаев, когда возвращаются DataFrame() или NamedTuple(), тогда заданная группа пропускается.

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

Чтобы применить функцию (function) к каждой строке, а не ко всем столбцам, ее можно заключить в структуру ByRow. cols может быть любым синтаксисом индексирования столбцов. Тогда функции (function) будет передан один аргумент для каждого из столбцов, указанных с помощью cols, или NamedTuple, если указанные столбцы заключены в AsTable. Если используется ByRow, cols может выбрать пустой набор столбцов, тогда function вызывается для каждой строки без аргументов, и передается пустой NamedTuple, если в AsTable заключен пустой набор столбцов.

Если передается коллекция имен столбцов, то принимаются запросы дублирующихся имен столбцов в целевом фрейме данных (например, допускается select!(df, [:a], :, r"a")), и используется только первое вхождение. В частности, используется следующий синтаксис для перемещения столбца :col в первую позицию во фрейме данных — select!(df, :col, :). Напротив, имена выходных столбцов в операциях переименования, преобразования и выбора одного столбца должны быть уникальными, поэтому, например, select!(df, :a, :a => :a) или select!(df, :a, :a => ByRow(sin) => :a) недопустимы.

В общем случае столбцы, возвращаемые преобразованиями, сохраняются в целевом фрейме данных без копирования. Исключением из этого правила являются случаи, когда столбцы из исходного фрейма данных повторно используются в целевом фрейме данных. Это можно сделать с помощью таких выражений, как: :x1, [:x1, :x2], :x1 => :x2, :x1 => identity => :x2 или :x1 => (x -> @view x[inds]) (обратите внимание, что в последнем случае исходный столбец используется повторно косвенным образом через представление). В таких случаях поведение зависит от значения именованного аргумента copycols:

  • если copycols=true, в результате таких преобразований всегда создается копия исходного столбца или его представления;

  • если copycols=false, копии создаются только для того, чтобы избежать многократного хранения одного и того же столбца в целевом фрейме данных. Точнее, при первом использовании столбца копирование не производится, но при каждом последующем повторном использовании исходного столбца (при сравнении с использованием ===, которое исключает представления исходных столбцов) создается копия.

Обратите внимание, что при выполнении transform! или select! предполагается, что copycols=false.

Если df является SubDataFrame и copycols=true, возвращается DataFrame и применяются те же правила копирования, что и для входных данных DataFrame: это означает, в частности, что выбранные столбцы будут скопированы. При copycols=false SubDataFrame возвращается без копирования столбцов, и в этом случае преобразование или переименование столбцов не допускается.

Если передается GroupedDataFrame и threads=true (по умолчанию), для каждого указанного преобразования порождается отдельная задача. Затем каждое преобразование порождает столько задач, сколько потоков доступно в Julia, и разделяет обработку групп между ними (однако в настоящее время преобразования с оптимизированной реализацией, такие как sum, и преобразования, возвращающие несколько строк, используют одну задачу для всех групп). Это позволяет выполнять параллельную работу, если среда Julia была запущена с несколькими потоками. Поэтому передаваемые функции преобразования не должны изменять глобальные переменные (то есть они должны быть чистыми), использовать блокировки для управления параллельным доступом, либо следует передать threads=false, чтобы отключить многопоточность. В будущем параллелизм может быть распространен и на другие случаи, так что это требование справедливо и для входных данных DataFrame.

Для повышения производительности операций некоторые преобразования используют оптимизированную реализацию. Дополнительные сведения см. в описании DataFrames.table_transformation.

Именованные аргументы

  • copycols::Bool=true: следует ли копировать столбцы исходного фрейма данных, если к ним не применены преобразования.

  • renamecols::Bool=true: должны ли автоматически генерируемые имена столбцов в форме cols => function включать название функций преобразования, или нет.

  • keepkeys::Bool=true: должны ли группирующие столбцы gd сохраняться в возвращаемом фрейме данных.

  • ungroup::Bool=true: должно ли возвращаемое значение операции с gd быть фреймом данных или GroupedDataFrame.

  • threads::Bool=true: могут ли преобразования осуществляться в отдельных задачах, которые могут выполняться параллельно (возможно, с применением к нескольким строкам или группам одновременно). Тот момент, порождаются ли задачи, и их количество определяется автоматически. Установите значение false, если некоторые преобразования требуют последовательного выполнения или не являются потокобезопасными.

Метаданные: эта функция распространяет метаданные на уровне таблиц в стиле :note. Метаданные на уровне столбцов в стиле :note распространяются в следующих случаях: а) один столбец преобразуется в один столбец, при этом имя столбца не изменяется (это относится ко всем операциям выбора столбца), или б) один столбец преобразуется с помощью identity или copy в один столбец даже при изменении имени столбца (сюда относится и переименование столбца). Особый случай для GroupedDataFrame: если вывод имеет то же имя, что и группирующий столбец, и keepkeys=true, метаданные берутся из исходного группирующего столбца.

Примеры

julia> df = DataFrame(a=1:3, b=4:6)
3×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      4
   2 │     2      5
   3 │     3      6

julia> select(df, 2)
3×1 DataFrame
 Row │ b
     │ Int64
─────┼───────
   1 │     4
   2 │     5
   3 │     6

julia> select(df, :a => ByRow(sin) => :c, :b)
3×2 DataFrame
 Row │ c         b
     │ Float64   Int64
─────┼─────────────────
   1 │ 0.841471      4
   2 │ 0.909297      5
   3 │ 0.14112       6

julia> select(df, :, [:a, :b] => (a, b) -> a .+ b .- sum(b)/length(b))
3×3 DataFrame
 Row │ a      b      a_b_function
     │ Int64  Int64  Float64
─────┼────────────────────────────
   1 │     1      4           0.0
   2 │     2      5           2.0
   3 │     3      6           4.0

julia> select(df, All() .=> [minimum maximum])
3×4 DataFrame
 Row │ a_minimum  b_minimum  a_maximum  b_maximum
     │ Int64      Int64      Int64      Int64
─────┼────────────────────────────────────────────
   1 │         1          4          3          6
   2 │         1          4          3          6
   3 │         1          4          3          6

julia> using Statistics

julia> select(df, AsTable(:) => ByRow(mean), renamecols=false)
3×1 DataFrame
 Row │ a_b
     │ Float64
─────┼─────────
   1 │     2.5
   2 │     3.5
   3 │     4.5

julia> select(df, AsTable(:) => ByRow(mean) => x -> join(x, "_"))
3×1 DataFrame
 Row │ a_b
     │ Float64
─────┼─────────
   1 │     2.5
   2 │     3.5
   3 │     4.5

julia> select(first, df)
3×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      4
   2 │     1      4
   3 │     1      4

julia> df = DataFrame(a=1:3, b=4:6, c=7:9)
3×3 DataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      4      7
   2 │     2      5      8
   3 │     3      6      9

julia> select(df, AsTable(:) => ByRow(x -> (mean=mean(x), std=std(x))) => :stats,
              AsTable(:) => ByRow(x -> (mean=mean(x), std=std(x))) => AsTable)
3×3 DataFrame
 Row │ stats                    mean     std
     │ NamedTup…                Float64  Float64
─────┼───────────────────────────────────────────
   1 │ (mean = 4.0, std = 3.0)      4.0      3.0
   2 │ (mean = 5.0, std = 3.0)      5.0      3.0
   3 │ (mean = 6.0, std = 3.0)      6.0      3.0

julia> df = DataFrame(a=[1, 1, 1, 2, 2, 1, 1, 2],
                      b=repeat([2, 1], outer=[4]),
                      c=1:8)
8×3 DataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      2      1
   2 │     1      1      2
   3 │     1      2      3
   4 │     2      1      4
   5 │     2      2      5
   6 │     1      1      6
   7 │     1      2      7
   8 │     2      1      8

julia> gd = groupby(df, :a)
GroupedDataFrame with 2 groups based on key: a
First Group (5 rows): a = 1
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      2      1
   2 │     1      1      2
   3 │     1      2      3
   4 │     1      1      6
   5 │     1      2      7
⋮
Last Group (3 rows): a = 2
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     2      1      4
   2 │     2      2      5
   3 │     2      1      8

указание имени для целевого столбца

julia> df = DataFrame(a=[1, 1, 1, 2, 2, 1, 1, 2],
                      b=repeat([2, 1], outer=[4]),
                      c=1:8);

julia> gd = groupby(df, :a);

julia> select(gd, :c => (x -> sum(log, x)) => :sum_log_c)
8×2 DataFrame
 Row │ a      sum_log_c
     │ Int64  Float64
─────┼──────────────────
   1 │     1    5.52943
   2 │     1    5.52943
   3 │     1    5.52943
   4 │     2    5.07517
   5 │     2    5.07517
   6 │     1    5.52943
   7 │     1    5.52943
   8 │     2    5.07517

julia> select(gd, [:b, :c] .=> sum) # передача вектора пар
8×3 DataFrame
 Row │ a      b_sum  c_sum
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      8     19
   2 │     1      8     19
   3 │     1      8     19
   4 │     2      4     17
   5 │     2      4     17
   6 │     1      8     19
   7 │     1      8     19
   8 │     2      4     17

несколько аргументов, переименование и сохранение ключей

julia> df = DataFrame(a=[1, 1, 1, 2, 2, 1, 1, 2],
                      b=repeat([2, 1], outer=[4]),
                      c=1:8);

julia> gd = groupby(df, :a);

julia> select(gd, :b => :b1, :c => :c1, [:b, :c] => +, keepkeys=false)
8×3 DataFrame
 Row │ b1     c1     b_c_+
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     2      1      3
   2 │     1      2      3
   3 │     2      3      5
   4 │     1      4      5
   5 │     2      5      7
   6 │     1      6      7
   7 │     2      7      9
   8 │     1      8      9

трансляция и расширение столбцов

julia> df = DataFrame(a=[1, 1, 1, 2, 2, 1, 1, 2],
                      b=repeat([2, 1], outer=[4]),
                      c=1:8);

julia> gd = groupby(df, :a);

julia> select(gd, :b, AsTable([:b, :c]) => ByRow(extrema) => [:min, :max])
8×4 DataFrame
 Row │ a      b      min    max
     │ Int64  Int64  Int64  Int64
─────┼────────────────────────────
   1 │     1      2      1      2
   2 │     1      1      1      2
   3 │     1      2      2      3
   4 │     2      1      1      4
   5 │     2      2      2      5
   6 │     1      1      1      6
   7 │     1      2      2      7
   8 │     2      1      1      8

julia> select(gd, :, AsTable(Not(:a)) => sum, renamecols=false)
8×4 DataFrame
 Row │ a      b      c      b_c
     │ Int64  Int64  Int64  Int64
─────┼────────────────────────────
   1 │     1      2      1      3
   2 │     1      1      2      3
   3 │     1      2      3      5
   4 │     2      1      4      5
   5 │     2      2      5      7
   6 │     1      1      6      7
   7 │     1      2      7      9
   8 │     2      1      8      9

независимые от столбцов операции

julia> df = DataFrame(a=[1, 1, 1, 2, 2, 1, 1, 2],
                      b=repeat([2, 1], outer=[4]),
                      c=1:8);

julia> gd = groupby(df, :a);

julia> select(gd, nrow, proprow, groupindices, eachindex)
8×5 DataFrame
 Row │ a      nrow   proprow  groupindices  eachindex
     │ Int64  Int64  Float64  Int64         Int64
─────┼────────────────────────────────────────────────
   1 │     1      5    0.625             1          1
   2 │     1      5    0.625             1          2
   3 │     1      5    0.625             1          3
   4 │     2      3    0.375             2          1
   5 │     2      3    0.375             2          2
   6 │     1      5    0.625             1          4
   7 │     1      5    0.625             1          5
   8 │     2      3    0.375             2          3

# DataFrames.select!Function

select!(df::AbstractDataFrame, args...;
        renamecols::Bool=true, threads::Bool=true)
select!(args::Base.Callable, df::DataFrame;
        renamecols::Bool=true, threads::Bool=true)
select!(gd::GroupedDataFrame, args...; ungroup::Bool=true,
        renamecols::Bool=true, threads::Bool=true)
select!(f::Base.Callable, gd::GroupedDataFrame; ungroup::Bool=true,
        renamecols::Bool=true, threads::Bool=true)

Изменяет df или gd на месте для сохранения только столбцов или преобразований, указанных с помощью args..., и возвращает его. Результат гарантированно имеет то же количество строк, что и df или родитель gd, за исключением ситуаций, когда ни один столбец не выбран (в этом случае результат не содержит строк).

Если передается SubDataFrame или GroupedDataFrame{SubDataFrame}, родительский фрейм данных обновляется с помощью столбцов, созданных args..., следуя тем же правилам, что и при индексировании:

  • для существующих столбцов отфильтрованные строки заполняются значениями, присутствующими в старых столбцах

  • для новых столбцов (что допустимо, только если SubDataFrame был создан с помощью : в качестве селектора столбцов) отфильтрованные строки заполняются отсутствующими (missing) значениями

  • отброшенных столбцов (допускаются, только если SubDataFrame был создан с помощью : в качестве селектора столбцов), которые удаляются,

  • если SubDataFrame не был создан с помощью : в качестве селектора столбцов, select! разрешен только в том случае, если преобразования сохраняют точно такую же последовательность имен столбцов, что и в переданном df.

Если передается GroupedDataFrame, он обновляется, чтобы отразить новые строки своего обновленного родителя. Если существуют независимые объекты GroupedDataFrame, созданные на основе одного и того же родительского фрейма данных, они могут быть повреждены.

Ниже подробно описаны и сопоставлены общие правила для всех функций преобразования, поддерживаемых DataFrames.jl.

Все эти операции поддерживаются как для AbstractDataFrame (при пропуске шагов разделения и объединения), так и для GroupedDataFrame. Технически AbstractDataFrame считается сгруппированным без столбцов (это означает, что у него есть одна группа или ни одной, если он пуст). Единственное отличие заключается в том, что в этом случае именованные аргументы keepkeys и ungroup (описанные ниже) не поддерживаются, и всегда возвращается фрейм данных, поскольку в этом случае нет шагов разделения и объединения.

Чтобы выполнять операции с группами, сначала нужно создать объект GroupedDataFrame из фрейма данных с помощью функции groupby, которая принимает два аргумента: (1) фрейм данных, который нужно сгруппировать, и (2) набор столбцов, по которым осуществляется группировка.

Затем можно применить операции к каждой группе с помощью одной из следующих функций:

  • combine: не накладывает ограничений на количество возвращаемых строк в каждой группе; возвращаемые значения конкатенируются по вертикали в соответствии с порядком групп в GroupedDataFrame; обычно используется для вычисления сводной статистики по группам; для GroupedDataFrame, если группирующие столбцы сохраняются, они помещаются первыми в результат;

  • select: возвращает фрейм данных с количеством и порядком строк, точно таким же, как в исходном фрейме данных, включая только новые вычисленные столбцы; select! является версией на месте для select; для GroupedDataFrame, если группирующие столбцы сохраняются, они помещаются первыми в результат;

  • transform: возвращает фрейм данных с количеством и порядком строк, точно таким же, как в исходном фрейме данных, включая все столбцы из исходного фрейма и новые вычисленные столбцы; transform! является версией на месте для transform; существующие столбцы в исходном фрейме данных помещаются первыми в результат.

Особый случай: если передается GroupedDataFrame без групп, результат операции определяется путем выполнения одного вызова функции преобразования с переданным ей аргументом с нулем строк. Выходные данные этой операции используются только для определения количества и типа созданных столбцов, но результат не содержит строк.

Все эти функции принимают спецификацию одной или нескольких функций для применения к каждому подмножеству DataFrame. Эта спецификация может иметь следующий вид:

  1. Стандартные селекторы столбцов (целые числа, символы (Symbol), строки, векторы целых чисел, векторы символов (Symbol), векторы строк, All, Cols, :, Between, Not и регулярные выражения).

  2. Пара cols => function, указывающая, что функцию (function) следует вызывать с позиционными аргументами, содержащими столбцы cols, которые могут быть любым допустимым селектором столбцов. В этом случае имя целевого столбца генерируется автоматически и предполагается, что функция (function) возвращает единичное значение или вектор. Сгенерированное имя создается путем конкатенации имени исходного столбца и имени функции (function) по умолчанию (см. примеры ниже).

  3. Форма cols => function => target_cols, дополнительно явно указывающая целевой столбец или столбцы, которые должны быть одним именем (как Symbol или строка), вектором имен или AsTable. Кроме того, это может быть функция (Function), которая принимает в качестве аргумента строку или вектор строк, содержащие имена столбцов, выбранные с помощью cols, и возвращает имена целевых столбцов (допускаются все принятые типы, кроме AsTable).

  4. Пара col => target_cols, которая переименовывает столбец col в target_cols, который должен быть одним именем (как Symbol или строка), вектором имен или AsTable.

  5. Независимые от столбцов операции function => target_cols или просто function для конкретных функций (function), где входные столбцы опущены; без target_cols новый столбец имеет то же имя, что и function, в противном случае должен быть одним именем (как Symbol или строка). Поддерживаются следующие функции (function).

    • nrow для эффективного вычисления количества строк в каждой группе.

    • proprow для эффективного вычисления доли строк в каждой группе.

    • eachindex для возврата вектора, содержащего номер каждой строки в каждой группе.

    • groupindices для возврата номера группы.

  6. Векторы или матрицы, содержащие преобразования, заданные синтаксисом Pair, описываются в пунктах 2—​5.

  7. Функция, которая будет вызвана с SubDataFrame, соответствующим каждой группе, если обрабатывается GroupedDataFrame, или с самим фреймом данных, если обрабатывается AbstractDataFrame. Эту форму не рекомендуется использовать из-за ее низкой производительности, за исключением случаев, когда количество групп невелико или обрабатывается очень большое количество столбцов (в этом случае SubDataFrame позволяет избежать чрезмерной компиляции).

Примечание. Если передается выражение вида x => y, то, за исключением специального вспомогательного вида nrow => target_cols, оно всегда интерпретируется как cols => function. В частности, следующее выражение function => target_cols не является допустимой спецификацией преобразования.

Примечание. Если cols или target_cols являются All, Cols, Between или Not, поддерживается трансляция с использованием .=>, и она эквивалентна трансляции результата names(df, cols) или names(df, target_cols). Это работает, как будто трансляция произошла после замены селектора выбранными именами столбцов в области фрейма данных.

Все функции имеют два типа сигнатур. Один из них принимает GroupedDataFrame в качестве первого аргумента и произвольное количество преобразований, описанных выше, в качестве последующих аргументов. Второй тип сигнатуры — это когда в качестве первого аргумента передается Function или Type и GroupedDataFrame в качестве второго аргумента (аналогично map).

Есть особое правило: если при использовании синтаксисов cols => function и cols => function => target_cols cols заключен в объект AsTable, NamedTuple, содержащий столбцы, выбранные с помощью cols, передается function. Дополнительные сведения см. в документации по DataFrames.table_transformation, где также рассматриваются вопросы производительности.

Результат, который может возвращать функция (function), определяется значением target_cols.

  1. Если cols и target_cols опущены (передается только function), при возврате фрейма данных, матрицы, NamedTuple, Tables.AbstractRow или DataFrameRow будет создано несколько столбцов. При возврате любого другого значения создается один столбец.

  2. Если target_cols является символом (Symbol) или строкой, предполагается, что функция возвратит один столбец. В этом случае при возврате фрейма данных, матрицы, NamedTuple, Tables.AbstractRow или DataFrameRow возникнет ошибка.

  3. Если target_cols является вектором символов (Symbol) или строк или AsTable, предполагается, что функция (function) возвратит несколько столбцов. Если функция (function) возвращает какой-либо элемент из AbstractDataFrame, NamedTuple, DataFrameRow, Tables.AbstractRow, AbstractMatrix, применяется правило, описанное в пункте 1 выше. Если функция (function) возвращает AbstractVector, каждый элемент этого вектора должен поддерживать функцию keys, которая должна возвращать коллекцию Symbol, строк или целых чисел. Возвращаемое значение keys должно быть одинаковым для всех элементов. Затем создается столько столбцов, сколько элементов содержится в возвращаемом значении функции keys. Если target_cols является AsTable, их имена задаются равными именам ключей, за исключением случаев, когда keys возвращает целые числа, тогда они получают префикс x (таким образом, имена столбцов будут выглядеть как x1, x2 и т. д.). Если target_cols является вектором символов (Symbol) или строк, имена столбцов, созданные на основе приведенных выше правил, игнорируются и заменяются target_cols (в этом случае количество столбцов должно совпадать с длиной target_cols). Если fun возвращает значение любого другого типа, предполагается, что это таблица, соответствующая API Tables.jl, и для нее вызывается функция Tables.columntable для получения результирующих столбцов и их имен. Имена сохраняются, когда target_cols является AsTable, и заменяются, если target_cols является вектором символов (Symbol) или строк.

Во всех этих случаях функция (function) может возвращать как одну строку, так и несколько. Как правило, значения, заключенные в Ref или 0-мерный массив AbstractArray, распаковываются и после этого считаются одной строкой.

select/select! и transform/transform! всегда возвращают фрейм данных с количеством и порядком строк, точно таким же, как у исходного (даже если в GroupedDataFrame был изменен порядок групп), за исключением случаев, когда в результирующем фрейме данных нет столбцов (в этом случае результат не содержит строк).

Для combine строки в возвращаемом объекте отображаются в порядке групп в GroupedDataFrame. Функции могут возвращать произвольное количество строк для каждой группы, но тип возвращаемого объекта и количество и имена столбцов должны быть одинаковыми для всех групп, за исключением случаев, когда возвращаются DataFrame() или NamedTuple(), тогда заданная группа пропускается.

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

Чтобы применить функцию (function) к каждой строке, а не ко всем столбцам, ее можно заключить в структуру ByRow. cols может быть любым синтаксисом индексирования столбцов. Тогда функции (function) будет передан один аргумент для каждого из столбцов, указанных с помощью cols, или NamedTuple, если указанные столбцы заключены в AsTable. Если используется ByRow, cols может выбрать пустой набор столбцов, тогда function вызывается для каждой строки без аргументов, и передается пустой NamedTuple, если в AsTable заключен пустой набор столбцов.

Если передается коллекция имен столбцов, то принимаются запросы дублирующихся имен столбцов в целевом фрейме данных (например, допускается select!(df, [:a], :, r"a")), и используется только первое вхождение. В частности, используется следующий синтаксис для перемещения столбца :col в первую позицию во фрейме данных — select!(df, :col, :). Напротив, имена выходных столбцов в операциях переименования, преобразования и выбора одного столбца должны быть уникальными, поэтому, например, select!(df, :a, :a => :a) или select!(df, :a, :a => ByRow(sin) => :a) недопустимы.

В общем случае столбцы, возвращаемые преобразованиями, сохраняются в целевом фрейме данных без копирования. Исключением из этого правила являются случаи, когда столбцы из исходного фрейма данных повторно используются в целевом фрейме данных. Это можно сделать с помощью таких выражений, как: :x1, [:x1, :x2], :x1 => :x2, :x1 => identity => :x2 или :x1 => (x -> @view x[inds]) (обратите внимание, что в последнем случае исходный столбец используется повторно косвенным образом через представление). В таких случаях поведение зависит от значения именованного аргумента copycols:

  • если copycols=true, в результате таких преобразований всегда создается копия исходного столбца или его представления;

  • если copycols=false, копии создаются только для того, чтобы избежать многократного хранения одного и того же столбца в целевом фрейме данных. Точнее, при первом использовании столбца копирование не производится, но при каждом последующем повторном использовании исходного столбца (при сравнении с использованием ===, которое исключает представления исходных столбцов) создается копия.

Обратите внимание, что при выполнении transform! или select! предполагается, что copycols=false.

Если df является SubDataFrame и copycols=true, возвращается DataFrame и применяются те же правила копирования, что и для входных данных DataFrame: это означает, в частности, что выбранные столбцы будут скопированы. При copycols=false SubDataFrame возвращается без копирования столбцов, и в этом случае преобразование или переименование столбцов не допускается.

Если передается GroupedDataFrame и threads=true (по умолчанию), для каждого указанного преобразования порождается отдельная задача. Затем каждое преобразование порождает столько задач, сколько потоков доступно в Julia, и разделяет обработку групп между ними (однако в настоящее время преобразования с оптимизированной реализацией, такие как sum, и преобразования, возвращающие несколько строк, используют одну задачу для всех групп). Это позволяет выполнять параллельную работу, если среда Julia была запущена с несколькими потоками. Поэтому передаваемые функции преобразования не должны изменять глобальные переменные (то есть они должны быть чистыми), использовать блокировки для управления параллельным доступом, либо следует передать threads=false, чтобы отключить многопоточность. В будущем параллелизм может быть распространен и на другие случаи, так что это требование справедливо и для входных данных DataFrame.

Для повышения производительности операций некоторые преобразования используют оптимизированную реализацию. Дополнительные сведения см. в описании DataFrames.table_transformation.

Именованные аргументы

  • renamecols::Bool=true: должны ли автоматически генерируемые имена столбцов в форме cols => function включать название функций преобразования, или нет.

  • ungroup::Bool=true: должно ли возвращаемое значение операции с gd быть фреймом данных или GroupedDataFrame.

  • threads::Bool=true: могут ли преобразования осуществляться в отдельных задачах, которые могут выполняться параллельно (возможно, с применением к нескольким строкам или группам одновременно). Тот момент, порождаются ли задачи, и их количество определяется автоматически. Установите значение false, если некоторые преобразования требуют последовательного выполнения или не являются потокобезопасными.

Метаданные: эта функция распространяет метаданные на уровне таблиц в стиле :note. Метаданные на уровне столбцов в стиле :note распространяются в следующих случаях: а) один столбец преобразуется в один столбец, при этом имя столбца не изменяется (это относится ко всем операциям выбора столбца), или б) один столбец преобразуется с помощью identity или copy в один столбец даже при изменении имени столбца (сюда относится и переименование столбца). Особый случай для GroupedDataFrame: если вывод имеет то же имя, что и группирующий столбец, и keepkeys=true, метаданные берутся из исходного группирующего столбца.

Примеры см. в описании select.

# Random.shuffleFunction

shuffle([rng=GLOBAL_RNG,] df::AbstractDataFrame)

Возвращает копию df со случайно перестановленными строками. Необязательный аргумент rng указывает генератор случайных чисел.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Примеры

julia> using Random

julia> rng = MersenneTwister(1234);

julia> shuffle(rng, DataFrame(a=1:5, b=1:5))
5×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     2      2
   2 │     1      1
   3 │     4      4
   4 │     3      3
   5 │     5      5

# Random.shuffle!Function

shuffle!([rng=GLOBAL_RNG,] df::AbstractDataFrame)

Выполняет случайную перестановку строк df на месте. Необязательный аргумент rng указывает генератор случайных чисел.

shuffle! выдаст корректный результат, даже если некоторые столбцы переданного фрейма данных идентичны (проверены с помощью ===). В противном случае, если два столбца имеют общую часть памяти, но не идентичны (например, являются разными представлениями одного и того же родительского вектора), результат shuffle! может быть неверным.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Метаданные, имеющие другие стили, удаляются (из родительского фрейма данных, если df является SubDataFrame).

Примеры

julia> using Random

julia> rng = MersenneTwister(1234);

julia> shuffle!(rng, DataFrame(a=1:5, b=1:5))
5×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     2      2
   2 │     1      1
   3 │     4      4
   4 │     3      3
   5 │     5      5

# DataFrames.table_transformationFunction

table_transformation(df_sel::AbstractDataFrame, fun)

Это функция, вызываемая при запросе AsTable(...) => fun. Аргумент df_sel представляет собой фрейм данных, хранящий столбцы, выбранные с помощью селектора AsTable(...) .

По умолчанию он вызывает default_table_transformation. Однако разрешается добавлять специальные методы для определенных типов fun, если результат совпадает с тем, что выдает default_table_transformation, за исключением того, что разрешается выполнять преобразование eltype результирующих векторов или продвижение типов значений, которые согласованы с promote_type.

Гарантируется, что df_sel имеет как минимум один столбец.

Основное назначение специальных методов table_transformation — обеспечить более эффективную, чем заданную по умолчанию, реализацию запрошенного преобразования fun.

В будущем эта функция может стать частью общедоступного API пакета DataFrames.jl. Сейчас она должна рассматриваться как экспериментальная.

Быстрые пути реализованы в пакете DataFrames.jl для следующих функций fun:

  • sum, ByRow(sum), ByRow(sum∘skipmissing)

  • length, ByRow(length), ByRow(length∘skipmissing)

  • mean, ByRow(mean), ByRow(mean∘skipmissing)

  • ByRow(var), ByRow(var∘skipmissing)

  • ByRow(std), ByRow(std∘skipmissing)

  • ByRow(median), ByRow(median∘skipmissing)

  • minimum, ByRow(minimum), ByRow(minimum∘skipmissing)

  • maximum, ByRow(maximum), ByRow(maximum∘skipmissing)

  • fun∘collect и ByRow(fun∘collect), где fun является любой функцией

Обратите внимание, что для повышения производительности ByRow(sum), ByRow(sum∘skipmissing), ByRow(mean) и ByRow(mean∘skipmissing) выполняют все операции в целевом типе элемента. В некоторых очень редких случаях (например, смешивание очень больших значений Int64 и значений Float64) может быть получен результат, отличный от того, который мог бы получен при вызове функции вне DataFrames.jl. Чтобы избежать этой потери точности, следует использовать анонимную функцию, например вместо ByRow(sum) использовать ByRow(x -> sum(x)). Однако в целом для таких сценариев не следует рассматривать даже стандартные функции агрегирования, чтобы получить надежный результат, и пользователям рекомендуется перейти на вычисления с более высокой точностью. Ниже приведен пример случая, когда стандартная функция sum затрагивается обсуждаемой ситуацией.

julia> sum(Any[typemax(Int), typemax(Int), 1.0])
-1.0

julia> sum(Any[1.0, typemax(Int), typemax(Int)])
1.8446744073709552e19

# DataFrames.transformFunction

transform(df::AbstractDataFrame, args...;
          copycols::Bool=true, renamecols::Bool=true, threads::Bool=true)
transform(f::Callable, df::DataFrame;
          renamecols::Bool=true, threads::Bool=true)
transform(gd::GroupedDataFrame, args...;
          copycols::Bool=true, keepkeys::Bool=true, ungroup::Bool=true,
          renamecols::Bool=true, threads::Bool=true)
transform(f::Base.Callable, gd::GroupedDataFrame;
          copycols::Bool=true, keepkeys::Bool=true, ungroup::Bool=true,
          renamecols::Bool=true, threads::Bool=true)

Создает новый фрейм данных, содержащий столбцы из df или gd, а также столбцы, указанные с помощью args, и возвращает его. Результат гарантированно имеет то же количество строк, что и df. Функция эквивалентна select(df, :, args...) или select(gd, :, args...).

Ниже подробно описаны и сопоставлены общие правила для всех функций преобразования, поддерживаемых DataFrames.jl.

Все эти операции поддерживаются как для AbstractDataFrame (при пропуске шагов разделения и объединения), так и для GroupedDataFrame. Технически AbstractDataFrame считается сгруппированным без столбцов (это означает, что у него есть одна группа или ни одной, если он пуст). Единственное отличие заключается в том, что в этом случае именованные аргументы keepkeys и ungroup (описанные ниже) не поддерживаются, и всегда возвращается фрейм данных, поскольку в этом случае нет шагов разделения и объединения.

Чтобы выполнять операции с группами, сначала нужно создать объект GroupedDataFrame из фрейма данных с помощью функции groupby, которая принимает два аргумента: (1) фрейм данных, который нужно сгруппировать, и (2) набор столбцов, по которым осуществляется группировка.

Затем можно применить операции к каждой группе с помощью одной из следующих функций:

  • combine: не накладывает ограничений на количество возвращаемых строк в каждой группе; возвращаемые значения конкатенируются по вертикали в соответствии с порядком групп в GroupedDataFrame; обычно используется для вычисления сводной статистики по группам; для GroupedDataFrame, если группирующие столбцы сохраняются, они помещаются первыми в результат;

  • select: возвращает фрейм данных с количеством и порядком строк, точно таким же, как в исходном фрейме данных, включая только новые вычисленные столбцы; select! является версией на месте для select; для GroupedDataFrame, если группирующие столбцы сохраняются, они помещаются первыми в результат;

  • transform: возвращает фрейм данных с количеством и порядком строк, точно таким же, как в исходном фрейме данных, включая все столбцы из исходного фрейма и новые вычисленные столбцы; transform! является версией на месте для transform; существующие столбцы в исходном фрейме данных помещаются первыми в результат.

Особый случай: если передается GroupedDataFrame без групп, результат операции определяется путем выполнения одного вызова функции преобразования с переданным ей аргументом с нулем строк. Выходные данные этой операции используются только для определения количества и типа созданных столбцов, но результат не содержит строк.

Все эти функции принимают спецификацию одной или нескольких функций для применения к каждому подмножеству DataFrame. Эта спецификация может иметь следующий вид:

  1. Стандартные селекторы столбцов (целые числа, символы (Symbol), строки, векторы целых чисел, векторы символов (Symbol), векторы строк, All, Cols, :, Between, Not и регулярные выражения).

  2. Пара cols => function, указывающая, что функцию (function) следует вызывать с позиционными аргументами, содержащими столбцы cols, которые могут быть любым допустимым селектором столбцов. В этом случае имя целевого столбца генерируется автоматически и предполагается, что функция (function) возвращает единичное значение или вектор. Сгенерированное имя создается путем конкатенации имени исходного столбца и имени функции (function) по умолчанию (см. примеры ниже).

  3. Форма cols => function => target_cols, дополнительно явно указывающая целевой столбец или столбцы, которые должны быть одним именем (как Symbol или строка), вектором имен или AsTable. Кроме того, это может быть функция (Function), которая принимает в качестве аргумента строку или вектор строк, содержащие имена столбцов, выбранные с помощью cols, и возвращает имена целевых столбцов (допускаются все принятые типы, кроме AsTable).

  4. Пара col => target_cols, которая переименовывает столбец col в target_cols, который должен быть одним именем (как Symbol или строка), вектором имен или AsTable.

  5. Независимые от столбцов операции function => target_cols или просто function для конкретных функций (function), где входные столбцы опущены; без target_cols новый столбец имеет то же имя, что и function, в противном случае должен быть одним именем (как Symbol или строка). Поддерживаются следующие функции (function).

    • nrow для эффективного вычисления количества строк в каждой группе.

    • proprow для эффективного вычисления доли строк в каждой группе.

    • eachindex для возврата вектора, содержащего номер каждой строки в каждой группе.

    • groupindices для возврата номера группы.

  6. Векторы или матрицы, содержащие преобразования, заданные синтаксисом Pair, описываются в пунктах 2—​5.

  7. Функция, которая будет вызвана с SubDataFrame, соответствующим каждой группе, если обрабатывается GroupedDataFrame, или с самим фреймом данных, если обрабатывается AbstractDataFrame. Эту форму не рекомендуется использовать из-за ее низкой производительности, за исключением случаев, когда количество групп невелико или обрабатывается очень большое количество столбцов (в этом случае SubDataFrame позволяет избежать чрезмерной компиляции).

Примечание. Если передается выражение вида x => y, то, за исключением специального вспомогательного вида nrow => target_cols, оно всегда интерпретируется как cols => function. В частности, следующее выражение function => target_cols не является допустимой спецификацией преобразования.

Примечание. Если cols или target_cols являются All, Cols, Between или Not, поддерживается трансляция с использованием .=>, и она эквивалентна трансляции результата names(df, cols) или names(df, target_cols). Это работает, как будто трансляция произошла после замены селектора выбранными именами столбцов в области фрейма данных.

Все функции имеют два типа сигнатур. Один из них принимает GroupedDataFrame в качестве первого аргумента и произвольное количество преобразований, описанных выше, в качестве последующих аргументов. Второй тип сигнатуры — это когда в качестве первого аргумента передается Function или Type и GroupedDataFrame в качестве второго аргумента (аналогично map).

Есть особое правило: если при использовании синтаксисов cols => function и cols => function => target_cols cols заключен в объект AsTable, NamedTuple, содержащий столбцы, выбранные с помощью cols, передается function. Дополнительные сведения см. в документации по DataFrames.table_transformation, где также рассматриваются вопросы производительности.

Результат, который может возвращать функция (function), определяется значением target_cols.

  1. Если cols и target_cols опущены (передается только function), при возврате фрейма данных, матрицы, NamedTuple, Tables.AbstractRow или DataFrameRow будет создано несколько столбцов. При возврате любого другого значения создается один столбец.

  2. Если target_cols является символом (Symbol) или строкой, предполагается, что функция возвратит один столбец. В этом случае при возврате фрейма данных, матрицы, NamedTuple, Tables.AbstractRow или DataFrameRow возникнет ошибка.

  3. Если target_cols является вектором символов (Symbol) или строк или AsTable, предполагается, что функция (function) возвратит несколько столбцов. Если функция (function) возвращает какой-либо элемент из AbstractDataFrame, NamedTuple, DataFrameRow, Tables.AbstractRow, AbstractMatrix, применяется правило, описанное в пункте 1 выше. Если функция (function) возвращает AbstractVector, каждый элемент этого вектора должен поддерживать функцию keys, которая должна возвращать коллекцию Symbol, строк или целых чисел. Возвращаемое значение keys должно быть одинаковым для всех элементов. Затем создается столько столбцов, сколько элементов содержится в возвращаемом значении функции keys. Если target_cols является AsTable, их имена задаются равными именам ключей, за исключением случаев, когда keys возвращает целые числа, тогда они получают префикс x (таким образом, имена столбцов будут выглядеть как x1, x2 и т. д.). Если target_cols является вектором символов (Symbol) или строк, имена столбцов, созданные на основе приведенных выше правил, игнорируются и заменяются target_cols (в этом случае количество столбцов должно совпадать с длиной target_cols). Если fun возвращает значение любого другого типа, предполагается, что это таблица, соответствующая API Tables.jl, и для нее вызывается функция Tables.columntable для получения результирующих столбцов и их имен. Имена сохраняются, когда target_cols является AsTable, и заменяются, если target_cols является вектором символов (Symbol) или строк.

Во всех этих случаях функция (function) может возвращать как одну строку, так и несколько. Как правило, значения, заключенные в Ref или 0-мерный массив AbstractArray, распаковываются и после этого считаются одной строкой.

select/select! и transform/transform! всегда возвращают фрейм данных с количеством и порядком строк, точно таким же, как у исходного (даже если в GroupedDataFrame был изменен порядок групп), за исключением случаев, когда в результирующем фрейме данных нет столбцов (в этом случае результат не содержит строк).

Для combine строки в возвращаемом объекте отображаются в порядке групп в GroupedDataFrame. Функции могут возвращать произвольное количество строк для каждой группы, но тип возвращаемого объекта и количество и имена столбцов должны быть одинаковыми для всех групп, за исключением случаев, когда возвращаются DataFrame() или NamedTuple(), тогда заданная группа пропускается.

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

Чтобы применить функцию (function) к каждой строке, а не ко всем столбцам, ее можно заключить в структуру ByRow. cols может быть любым синтаксисом индексирования столбцов. Тогда функции (function) будет передан один аргумент для каждого из столбцов, указанных с помощью cols, или NamedTuple, если указанные столбцы заключены в AsTable. Если используется ByRow, cols может выбрать пустой набор столбцов, тогда function вызывается для каждой строки без аргументов, и передается пустой NamedTuple, если в AsTable заключен пустой набор столбцов.

Если передается коллекция имен столбцов, то принимаются запросы дублирующихся имен столбцов в целевом фрейме данных (например, допускается select!(df, [:a], :, r"a")), и используется только первое вхождение. В частности, используется следующий синтаксис для перемещения столбца :col в первую позицию во фрейме данных — select!(df, :col, :). Напротив, имена выходных столбцов в операциях переименования, преобразования и выбора одного столбца должны быть уникальными, поэтому, например, select!(df, :a, :a => :a) или select!(df, :a, :a => ByRow(sin) => :a) недопустимы.

В общем случае столбцы, возвращаемые преобразованиями, сохраняются в целевом фрейме данных без копирования. Исключением из этого правила являются случаи, когда столбцы из исходного фрейма данных повторно используются в целевом фрейме данных. Это можно сделать с помощью таких выражений, как: :x1, [:x1, :x2], :x1 => :x2, :x1 => identity => :x2 или :x1 => (x -> @view x[inds]) (обратите внимание, что в последнем случае исходный столбец используется повторно косвенным образом через представление). В таких случаях поведение зависит от значения именованного аргумента copycols:

  • если copycols=true, в результате таких преобразований всегда создается копия исходного столбца или его представления;

  • если copycols=false, копии создаются только для того, чтобы избежать многократного хранения одного и того же столбца в целевом фрейме данных. Точнее, при первом использовании столбца копирование не производится, но при каждом последующем повторном использовании исходного столбца (при сравнении с использованием ===, которое исключает представления исходных столбцов) создается копия.

Обратите внимание, что при выполнении transform! или select! предполагается, что copycols=false.

Если df является SubDataFrame и copycols=true, возвращается DataFrame и применяются те же правила копирования, что и для входных данных DataFrame: это означает, в частности, что выбранные столбцы будут скопированы. При copycols=false SubDataFrame возвращается без копирования столбцов, и в этом случае преобразование или переименование столбцов не допускается.

Если передается GroupedDataFrame и threads=true (по умолчанию), для каждого указанного преобразования порождается отдельная задача. Затем каждое преобразование порождает столько задач, сколько потоков доступно в Julia, и разделяет обработку групп между ними (однако в настоящее время преобразования с оптимизированной реализацией, такие как sum, и преобразования, возвращающие несколько строк, используют одну задачу для всех групп). Это позволяет выполнять параллельную работу, если среда Julia была запущена с несколькими потоками. Поэтому передаваемые функции преобразования не должны изменять глобальные переменные (то есть они должны быть чистыми), использовать блокировки для управления параллельным доступом, либо следует передать threads=false, чтобы отключить многопоточность. В будущем параллелизм может быть распространен и на другие случаи, так что это требование справедливо и для входных данных DataFrame.

Для повышения производительности операций некоторые преобразования используют оптимизированную реализацию. Дополнительные сведения см. в описании DataFrames.table_transformation.

Именованные аргументы

  • copycols::Bool=true: следует ли копировать столбцы исходного фрейма данных, если к ним не применены преобразования.

  • renamecols::Bool=true: должны ли автоматически генерируемые имена столбцов в форме cols => function включать название функций преобразования, или нет.

  • keepkeys::Bool=true: должны ли группирующие столбцы gd сохраняться в возвращаемом фрейме данных.

  • ungroup::Bool=true: должно ли возвращаемое значение операции с gd быть фреймом данных или GroupedDataFrame.

  • threads::Bool=true: могут ли преобразования осуществляться в отдельных задачах, которые могут выполняться параллельно (возможно, с применением к нескольким строкам или группам одновременно). Тот момент, порождаются ли задачи, и их количество определяется автоматически. Установите значение false, если некоторые преобразования требуют последовательного выполнения или не являются потокобезопасными.

Обратите внимание, что когда первым аргументом является GroupedDataFrame, требуется keepkeys=false, чтобы возвращать другое значение для группирующего столбца.

Метаданные: эта функция распространяет метаданные на уровне таблиц в стиле :note. Метаданные на уровне столбцов в стиле :note распространяются в следующих случаях: а) один столбец преобразуется в один столбец, при этом имя столбца не изменяется (это относится ко всем операциям выбора столбца), или б) один столбец преобразуется с помощью identity или copy в один столбец даже при изменении имени столбца (сюда относится и переименование столбца). Особый случай для GroupedDataFrame: если вывод имеет то же имя, что и группирующий столбец, и keepkeys=true, метаданные берутся из исходного группирующего столбца.

Примеры

julia> gdf = groupby(DataFrame(x=1:2), :x)
GroupedDataFrame with 2 groups based on key: x
First Group (1 row): x = 1
 Row │ x
     │ Int64
─────┼───────
   1 │     1
⋮
Last Group (1 row): x = 2
 Row │ x
     │ Int64
─────┼───────
   1 │     2

julia> transform(gdf, x -> (x=10,), keepkeys=false)
2×1 DataFrame
 Row │ x
     │ Int64
─────┼───────
   1 │    10
   2 │    10

julia> transform(gdf, x -> (x=10,), keepkeys=true)
ERROR: ArgumentError: column :x in returned data frame is not equal to grouping key :x

Дополнительные примеры см. в описании select.

# DataFrames.transform!Function

transform!(df::AbstractDataFrame, args...;
           renamecols::Bool=true, threads::Bool=true)
transform!(args::Callable, df::AbstractDataFrame;
           renamecols::Bool=true, threads::Bool=true)
transform!(gd::GroupedDataFrame, args...;
           ungroup::Bool=true, renamecols::Bool=true, threads::Bool=true)
transform!(f::Base.Callable, gd::GroupedDataFrame;
           ungroup::Bool=true, renamecols::Bool=true, threads::Bool=true)

Изменяет df или gd на месте для добавления столбцов, указанных с помощью args..., и возвращает его. Результат гарантированно имеет то же количество строк, что и df или Функция эквивалентна select!(df, :, args...) или select!(gd, :, args...), за исключением того, что при каждом переименовании столбца создается копия.

Ниже подробно описаны и сопоставлены общие правила для всех функций преобразования, поддерживаемых DataFrames.jl.

Все эти операции поддерживаются как для AbstractDataFrame (при пропуске шагов разделения и объединения), так и для GroupedDataFrame. Технически AbstractDataFrame считается сгруппированным без столбцов (это означает, что у него есть одна группа или ни одной, если он пуст). Единственное отличие заключается в том, что в этом случае именованные аргументы keepkeys и ungroup (описанные ниже) не поддерживаются, и всегда возвращается фрейм данных, поскольку в этом случае нет шагов разделения и объединения.

Чтобы выполнять операции с группами, сначала нужно создать объект GroupedDataFrame из фрейма данных с помощью функции groupby, которая принимает два аргумента: (1) фрейм данных, который нужно сгруппировать, и (2) набор столбцов, по которым осуществляется группировка.

Затем можно применить операции к каждой группе с помощью одной из следующих функций:

  • combine: не накладывает ограничений на количество возвращаемых строк в каждой группе; возвращаемые значения конкатенируются по вертикали в соответствии с порядком групп в GroupedDataFrame; обычно используется для вычисления сводной статистики по группам; для GroupedDataFrame, если группирующие столбцы сохраняются, они помещаются первыми в результат;

  • select: возвращает фрейм данных с количеством и порядком строк, точно таким же, как в исходном фрейме данных, включая только новые вычисленные столбцы; select! является версией на месте для select; для GroupedDataFrame, если группирующие столбцы сохраняются, они помещаются первыми в результат;

  • transform: возвращает фрейм данных с количеством и порядком строк, точно таким же, как в исходном фрейме данных, включая все столбцы из исходного фрейма и новые вычисленные столбцы; transform! является версией на месте для transform; существующие столбцы в исходном фрейме данных помещаются первыми в результат.

Особый случай: если передается GroupedDataFrame без групп, результат операции определяется путем выполнения одного вызова функции преобразования с переданным ей аргументом с нулем строк. Выходные данные этой операции используются только для определения количества и типа созданных столбцов, но результат не содержит строк.

Все эти функции принимают спецификацию одной или нескольких функций для применения к каждому подмножеству DataFrame. Эта спецификация может иметь следующий вид:

  1. Стандартные селекторы столбцов (целые числа, символы (Symbol), строки, векторы целых чисел, векторы символов (Symbol), векторы строк, All, Cols, :, Between, Not и регулярные выражения).

  2. Пара cols => function, указывающая, что функцию (function) следует вызывать с позиционными аргументами, содержащими столбцы cols, которые могут быть любым допустимым селектором столбцов. В этом случае имя целевого столбца генерируется автоматически и предполагается, что функция (function) возвращает единичное значение или вектор. Сгенерированное имя создается путем конкатенации имени исходного столбца и имени функции (function) по умолчанию (см. примеры ниже).

  3. Форма cols => function => target_cols, дополнительно явно указывающая целевой столбец или столбцы, которые должны быть одним именем (как Symbol или строка), вектором имен или AsTable. Кроме того, это может быть функция (Function), которая принимает в качестве аргумента строку или вектор строк, содержащие имена столбцов, выбранные с помощью cols, и возвращает имена целевых столбцов (допускаются все принятые типы, кроме AsTable).

  4. Пара col => target_cols, которая переименовывает столбец col в target_cols, который должен быть одним именем (как Symbol или строка), вектором имен или AsTable.

  5. Независимые от столбцов операции function => target_cols или просто function для конкретных функций (function), где входные столбцы опущены; без target_cols новый столбец имеет то же имя, что и function, в противном случае должен быть одним именем (как Symbol или строка). Поддерживаются следующие функции (function).

    • nrow для эффективного вычисления количества строк в каждой группе.

    • proprow для эффективного вычисления доли строк в каждой группе.

    • eachindex для возврата вектора, содержащего номер каждой строки в каждой группе.

    • groupindices для возврата номера группы.

  6. Векторы или матрицы, содержащие преобразования, заданные синтаксисом Pair, описываются в пунктах 2—​5.

  7. Функция, которая будет вызвана с SubDataFrame, соответствующим каждой группе, если обрабатывается GroupedDataFrame, или с самим фреймом данных, если обрабатывается AbstractDataFrame. Эту форму не рекомендуется использовать из-за ее низкой производительности, за исключением случаев, когда количество групп невелико или обрабатывается очень большое количество столбцов (в этом случае SubDataFrame позволяет избежать чрезмерной компиляции).

Примечание. Если передается выражение вида x => y, то, за исключением специального вспомогательного вида nrow => target_cols, оно всегда интерпретируется как cols => function. В частности, следующее выражение function => target_cols не является допустимой спецификацией преобразования.

Примечание. Если cols или target_cols являются All, Cols, Between или Not, поддерживается трансляция с использованием .=>, и она эквивалентна трансляции результата names(df, cols) или names(df, target_cols). Это работает, как будто трансляция произошла после замены селектора выбранными именами столбцов в области фрейма данных.

Все функции имеют два типа сигнатур. Один из них принимает GroupedDataFrame в качестве первого аргумента и произвольное количество преобразований, описанных выше, в качестве последующих аргументов. Второй тип сигнатуры — это когда в качестве первого аргумента передается Function или Type и GroupedDataFrame в качестве второго аргумента (аналогично map).

Есть особое правило: если при использовании синтаксисов cols => function и cols => function => target_cols cols заключен в объект AsTable, NamedTuple, содержащий столбцы, выбранные с помощью cols, передается function. Дополнительные сведения см. в документации по DataFrames.table_transformation, где также рассматриваются вопросы производительности.

Результат, который может возвращать функция (function), определяется значением target_cols.

  1. Если cols и target_cols опущены (передается только function), при возврате фрейма данных, матрицы, NamedTuple, Tables.AbstractRow или DataFrameRow будет создано несколько столбцов. При возврате любого другого значения создается один столбец.

  2. Если target_cols является символом (Symbol) или строкой, предполагается, что функция возвратит один столбец. В этом случае при возврате фрейма данных, матрицы, NamedTuple, Tables.AbstractRow или DataFrameRow возникнет ошибка.

  3. Если target_cols является вектором символов (Symbol) или строк или AsTable, предполагается, что функция (function) возвратит несколько столбцов. Если функция (function) возвращает какой-либо элемент из AbstractDataFrame, NamedTuple, DataFrameRow, Tables.AbstractRow, AbstractMatrix, применяется правило, описанное в пункте 1 выше. Если функция (function) возвращает AbstractVector, каждый элемент этого вектора должен поддерживать функцию keys, которая должна возвращать коллекцию Symbol, строк или целых чисел. Возвращаемое значение keys должно быть одинаковым для всех элементов. Затем создается столько столбцов, сколько элементов содержится в возвращаемом значении функции keys. Если target_cols является AsTable, их имена задаются равными именам ключей, за исключением случаев, когда keys возвращает целые числа, тогда они получают префикс x (таким образом, имена столбцов будут выглядеть как x1, x2 и т. д.). Если target_cols является вектором символов (Symbol) или строк, имена столбцов, созданные на основе приведенных выше правил, игнорируются и заменяются target_cols (в этом случае количество столбцов должно совпадать с длиной target_cols). Если fun возвращает значение любого другого типа, предполагается, что это таблица, соответствующая API Tables.jl, и для нее вызывается функция Tables.columntable для получения результирующих столбцов и их имен. Имена сохраняются, когда target_cols является AsTable, и заменяются, если target_cols является вектором символов (Symbol) или строк.

Во всех этих случаях функция (function) может возвращать как одну строку, так и несколько. Как правило, значения, заключенные в Ref или 0-мерный массив AbstractArray, распаковываются и после этого считаются одной строкой.

select/select! и transform/transform! всегда возвращают фрейм данных с количеством и порядком строк, точно таким же, как у исходного (даже если в GroupedDataFrame был изменен порядок групп), за исключением случаев, когда в результирующем фрейме данных нет столбцов (в этом случае результат не содержит строк).

Для combine строки в возвращаемом объекте отображаются в порядке групп в GroupedDataFrame. Функции могут возвращать произвольное количество строк для каждой группы, но тип возвращаемого объекта и количество и имена столбцов должны быть одинаковыми для всех групп, за исключением случаев, когда возвращаются DataFrame() или NamedTuple(), тогда заданная группа пропускается.

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

Чтобы применить функцию (function) к каждой строке, а не ко всем столбцам, ее можно заключить в структуру ByRow. cols может быть любым синтаксисом индексирования столбцов. Тогда функции (function) будет передан один аргумент для каждого из столбцов, указанных с помощью cols, или NamedTuple, если указанные столбцы заключены в AsTable. Если используется ByRow, cols может выбрать пустой набор столбцов, тогда function вызывается для каждой строки без аргументов, и передается пустой NamedTuple, если в AsTable заключен пустой набор столбцов.

Если передается коллекция имен столбцов, то принимаются запросы дублирующихся имен столбцов в целевом фрейме данных (например, допускается select!(df, [:a], :, r"a")), и используется только первое вхождение. В частности, используется следующий синтаксис для перемещения столбца :col в первую позицию во фрейме данных — select!(df, :col, :). Напротив, имена выходных столбцов в операциях переименования, преобразования и выбора одного столбца должны быть уникальными, поэтому, например, select!(df, :a, :a => :a) или select!(df, :a, :a => ByRow(sin) => :a) недопустимы.

В общем случае столбцы, возвращаемые преобразованиями, сохраняются в целевом фрейме данных без копирования. Исключением из этого правила являются случаи, когда столбцы из исходного фрейма данных повторно используются в целевом фрейме данных. Это можно сделать с помощью таких выражений, как: :x1, [:x1, :x2], :x1 => :x2, :x1 => identity => :x2 или :x1 => (x -> @view x[inds]) (обратите внимание, что в последнем случае исходный столбец используется повторно косвенным образом через представление). В таких случаях поведение зависит от значения именованного аргумента copycols:

  • если copycols=true, в результате таких преобразований всегда создается копия исходного столбца или его представления;

  • если copycols=false, копии создаются только для того, чтобы избежать многократного хранения одного и того же столбца в целевом фрейме данных. Точнее, при первом использовании столбца копирование не производится, но при каждом последующем повторном использовании исходного столбца (при сравнении с использованием ===, которое исключает представления исходных столбцов) создается копия.

Обратите внимание, что при выполнении transform! или select! предполагается, что copycols=false.

Если df является SubDataFrame и copycols=true, возвращается DataFrame и применяются те же правила копирования, что и для входных данных DataFrame: это означает, в частности, что выбранные столбцы будут скопированы. При copycols=false SubDataFrame возвращается без копирования столбцов, и в этом случае преобразование или переименование столбцов не допускается.

Если передается GroupedDataFrame и threads=true (по умолчанию), для каждого указанного преобразования порождается отдельная задача. Затем каждое преобразование порождает столько задач, сколько потоков доступно в Julia, и разделяет обработку групп между ними (однако в настоящее время преобразования с оптимизированной реализацией, такие как sum, и преобразования, возвращающие несколько строк, используют одну задачу для всех групп). Это позволяет выполнять параллельную работу, если среда Julia была запущена с несколькими потоками. Поэтому передаваемые функции преобразования не должны изменять глобальные переменные (то есть они должны быть чистыми), использовать блокировки для управления параллельным доступом, либо следует передать threads=false, чтобы отключить многопоточность. В будущем параллелизм может быть распространен и на другие случаи, так что это требование справедливо и для входных данных DataFrame.

Для повышения производительности операций некоторые преобразования используют оптимизированную реализацию. Дополнительные сведения см. в описании DataFrames.table_transformation.

Именованные аргументы

  • renamecols::Bool=true: должны ли автоматически генерируемые имена столбцов в форме cols => function включать название функций преобразования, или нет.

  • ungroup::Bool=true: должно ли возвращаемое значение операции с gd быть фреймом данных или GroupedDataFrame.

  • threads::Bool=true: могут ли преобразования осуществляться в отдельных задачах, которые могут выполняться параллельно (возможно, с применением к нескольким строкам или группам одновременно). Тот момент, порождаются ли задачи, и их количество определяется автоматически. Установите значение false, если некоторые преобразования требуют последовательного выполнения или не являются потокобезопасными.

Метаданные: эта функция распространяет метаданные на уровне таблиц в стиле :note. Метаданные на уровне столбцов в стиле :note распространяются в следующих случаях: а) один столбец преобразуется в один столбец, при этом имя столбца не изменяется (это относится ко всем операциям выбора столбца), или б) один столбец преобразуется с помощью identity или copy в один столбец даже при изменении имени столбца (сюда относится и переименование столбца). Особый случай для GroupedDataFrame: если вывод имеет то же имя, что и группирующий столбец, и keepkeys=true, метаданные берутся из исходного группирующего столбца.

Примеры см. в описании select.

# Base.vcatFunction

vcat(dfs::AbstractDataFrame...;
     cols::Union{Symbol, AbstractVector{Symbol},
                 AbstractVector{<:AbstractString}}=:setequal,
     source::Union{Nothing, Symbol, AbstractString,
                   Pair{<:Union{Symbol, AbstractString}, <:AbstractVector}}=nothing)

Выполняет вертикальную конкатенацию AbstractDataFrame.

Именованный аргумент cols определяет столбцы в возвращаемом фрейме данных.

  • :setequal: требует, чтобы все фреймы данных имели одинаковые имена столбцов без учета порядка. Если они появляются в разных порядках, используется порядок первого предоставленного фрейма данных.

  • :orderequal: требует, чтобы все фреймы данных имели одинаковые имена столбцов и находились в одинаковом порядке.

  • :intersect: сохраняются только столбцы, присутствующие во всех предоставленных фреймах данных. Если пересечение пусто, возвращается пустой фрейм данных.

  • :union: сохраняются столбцы, присутствующие как минимум в одном из предоставленных фреймов данных. Столбцы, отсутствующие в некоторых фреймах данных, заполняются missing, где это необходимо.

  • Вектор Symbol или строк: сохраняются только перечисленные столбцы. Столбцы, отсутствующие в некоторых фреймах данных, заполняются missing, где это необходимо.

Именованный аргумент source, если не nothing (по умолчанию), указывает дополнительный столбец, который будет добавлен в последнюю позицию результирующего фрейма данных, который будет идентифицировать исходный фрейм данных. Это может быть Symbol или AbstractString, в этом случае идентификатором будет номер переданного исходного фрейма данных, или пара (Pair), состоящая из Symbol или AbstractString и вектора, задающего идентификаторы фреймов данных (которые не обязательно должны быть уникальными). Имя исходного столбца не должно присутствовать ни в одном исходном фрейме данных.

Порядок столбцов определяется порядком их появления во включенных фреймах данных. Поиск осуществляется по заголовку первого фрейма данных, затем второго и т. д.

Типы элементов столбцов определяются с помощью promote_type, как и в случае с vcat для AbstractVector.

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

Метаданные: функция vcat распространяет метаданные на уровне таблиц в стиле :note для ключей, присутствующих во всех передаваемых фреймах данных и имеющих одинаковое значение. Функция vcat распространяет метаданные на уровне столбцов в стиле :note для ключей, присутствующих во всех передаваемых фреймах данных, содержащих этот столбец, и имеющих одинаковое значение.

Пример

julia> df1 = DataFrame(A=1:3, B=1:3)
3×2 DataFrame
 Row │ A      B
     │ Int64  Int64
─────┼──────────────
   1 │     1      1
   2 │     2      2
   3 │     3      3

julia> df2 = DataFrame(A=4:6, B=4:6)
3×2 DataFrame
 Row │ A      B
     │ Int64  Int64
─────┼──────────────
   1 │     4      4
   2 │     5      5
   3 │     6      6

julia> df3 = DataFrame(A=7:9, C=7:9)
3×2 DataFrame
 Row │ A      C
     │ Int64  Int64
─────┼──────────────
   1 │     7      7
   2 │     8      8
   3 │     9      9

julia> df4 = DataFrame()
0×0 DataFrame

julia> vcat(df1, df2)
6×2 DataFrame
 Row │ A      B
     │ Int64  Int64
─────┼──────────────
   1 │     1      1
   2 │     2      2
   3 │     3      3
   4 │     4      4
   5 │     5      5
   6 │     6      6

julia> vcat(df1, df3, cols=:union)
6×3 DataFrame
 Row │ A      B        C
     │ Int64  Int64?   Int64?
─────┼─────────────────────────
   1 │     1        1  missing
   2 │     2        2  missing
   3 │     3        3  missing
   4 │     7  missing        7
   5 │     8  missing        8
   6 │     9  missing        9

julia> vcat(df1, df3, cols=:intersect)
6×1 DataFrame
 Row │ A
     │ Int64
─────┼───────
   1 │     1
   2 │     2
   3 │     3
   4 │     7
   5 │     8
   6 │     9

julia> vcat(df4, df1)
3×2 DataFrame
 Row │ A      B
     │ Int64  Int64
─────┼──────────────
   1 │     1      1
   2 │     2      2
   3 │     3      3

julia> vcat(df1, df2, df3, df4, cols=:union, source="source")
9×4 DataFrame
 Row │ A      B        C        source
     │ Int64  Int64?   Int64?   Int64
─────┼─────────────────────────────────
   1 │     1        1  missing       1
   2 │     2        2  missing       1
   3 │     3        3  missing       1
   4 │     4        4  missing       2
   5 │     5        5  missing       2
   6 │     6        6  missing       2
   7 │     7  missing        7       3
   8 │     8  missing        8       3
   9 │     9  missing        9       3

julia> vcat(df1, df2, df4, df3, cols=:union, source=:source => 'a':'d')
9×4 DataFrame
 Row │ A      B        C        source
     │ Int64  Int64?   Int64?   Char
─────┼─────────────────────────────────
   1 │     1        1  missing  a
   2 │     2        2  missing  a
   3 │     3        3  missing  a
   4 │     4        4  missing  b
   5 │     5        5  missing  b
   6 │     6        6  missing  b
   7 │     7  missing        7  d
   8 │     8  missing        8  d
   9 │     9  missing        9  d

Изменение формы фреймов данных с высокой на широкую и наоборот

# Base.stackFunction

stack(df::AbstractDataFrame[, measure_vars[, id_vars] ];
      variable_name=:variable, value_name=:value,
      view::Bool=false, variable_eltype::Type=String)

Выполняет наложение фрейма данных df, т. е. преобразует его из широкого формата в длинный.

Возвращает длинноформатный DataFrame, содержащий столбцы для каждого id_vars, столбец value_name (:value по умолчанию), содержащий значения наложенных столбцов (measure_vars), и столбец variable_name (:variable по умолчанию) — вектор, содержащий имя соответствующей переменной measure_vars.

Если view=true, возвращает многослойное представление фрейма данных (длинный формат). Результатом является представление, поскольку столбцы представляют собой особые AbstractVectors, которые возвращают представления в исходный фрейм данных.

Аргументы

  • df: AbstractDataFrame для наложения.

  • measure_vars: столбцы для наложения (переменные измерения), в виде селектора столбцов (символ (Symbol), строка или целое число; :, Cols, All, Between, Not, регулярное выражение или вектор символов (Symbol), строк или целых чисел). Если measure_vars или id_vars не заданы, для measure_vars по умолчанию используются все столбцы с плавающей запятой.

  • id_vars: столбцы указателей, которые повторяются при наложении, в виде селектора столбцов (символ (Symbol), строка или целое число; :, Cols, All, Between, Not, регулярное выражение или вектор символов (Symbol), строк или целых чисел). По умолчанию используются все переменные, которые не являются measure_vars.

  • variable_name: имя (Symbol или строка) нового наложенного столбца, в котором будут храниться имена каждой переменной measure_vars.

  • value_name: имя (Symbol или строка) нового наложенного столбца, содержащего значения из каждой переменной measure_vars.

  • view: должен ли наложенный фрейм данных быть представлением, а не содержать только что выделенные векторы.

  • variable_eltype: определяет тип элемента столбца variable_name. По умолчанию создается PooledArray{String}. Если variable_eltype=Symbol, создается PooledVector{Symbol}, а если variable_eltype=CategoricalValue{String}, создается CategoricalArray{String} (при необходимости сначала следует вызывать using CategoricalArrays). При передаче любого другого типа T будет создан столбец PooledVector{T}, если он поддерживает преобразование из String. Если view=true, создается RepeatedVector{T}.

Метаданные: метаданные на уровне таблиц в стиле :note и метаданные на уровне столбцов в стиле :note для столбцов указателей.

Примеры

julia> df = DataFrame(a=repeat(1:3, inner=2),
                      b=repeat(1:2, inner=3),
                      c=repeat(1:1, inner=6),
                      d=repeat(1:6, inner=1),
                      e=string.('a':'f'))
6×5 DataFrame
 Row │ a      b      c      d      e
     │ Int64  Int64  Int64  Int64  String
─────┼────────────────────────────────────
   1 │     1      1      1      1  a
   2 │     1      1      1      2  b
   3 │     2      1      1      3  c
   4 │     2      2      1      4  d
   5 │     3      2      1      5  e
   6 │     3      2      1      6  f

julia> stack(df, [:c, :d])
12×5 DataFrame
 Row │ a      b      e       variable  value
     │ Int64  Int64  String  String    Int64
─────┼───────────────────────────────────────
   1 │     1      1  a       c             1
   2 │     1      1  b       c             1
   3 │     2      1  c       c             1
   4 │     2      2  d       c             1
   5 │     3      2  e       c             1
   6 │     3      2  f       c             1
   7 │     1      1  a       d             1
   8 │     1      1  b       d             2
   9 │     2      1  c       d             3
  10 │     2      2  d       d             4
  11 │     3      2  e       d             5
  12 │     3      2  f       d             6

julia> stack(df, [:c, :d], [:a])
12×3 DataFrame
 Row │ a      variable  value
     │ Int64  String    Int64
─────┼────────────────────────
   1 │     1  c             1
   2 │     1  c             1
   3 │     2  c             1
   4 │     2  c             1
   5 │     3  c             1
   6 │     3  c             1
   7 │     1  d             1
   8 │     1  d             2
   9 │     2  d             3
  10 │     2  d             4
  11 │     3  d             5
  12 │     3  d             6

julia> stack(df, Not([:a, :b, :e]))
12×5 DataFrame
 Row │ a      b      e       variable  value
     │ Int64  Int64  String  String    Int64
─────┼───────────────────────────────────────
   1 │     1      1  a       c             1
   2 │     1      1  b       c             1
   3 │     2      1  c       c             1
   4 │     2      2  d       c             1
   5 │     3      2  e       c             1
   6 │     3      2  f       c             1
   7 │     1      1  a       d             1
   8 │     1      1  b       d             2
   9 │     2      1  c       d             3
  10 │     2      2  d       d             4
  11 │     3      2  e       d             5
  12 │     3      2  f       d             6

julia> stack(df, Not([:a, :b, :e]), variable_name=:somemeasure)
12×5 DataFrame
 Row │ a      b      e       somemeasure  value
     │ Int64  Int64  String  String       Int64
─────┼──────────────────────────────────────────
   1 │     1      1  a       c                1
   2 │     1      1  b       c                1
   3 │     2      1  c       c                1
   4 │     2      2  d       c                1
   5 │     3      2  e       c                1
   6 │     3      2  f       c                1
   7 │     1      1  a       d                1
   8 │     1      1  b       d                2
   9 │     2      1  c       d                3
  10 │     2      2  d       d                4
  11 │     3      2  e       d                5
  12 │     3      2  f       d                6

# DataFrames.unstackFunction

unstack(df::AbstractDataFrame, rowkeys, colkey, value;
        renamecols::Function=identity, allowmissing::Bool=false,
        combine=only, fill=missing, threads::Bool=true)
unstack(df::AbstractDataFrame, colkey, value;
        renamecols::Function=identity, allowmissing::Bool=false,
        combine=only, fill=missing, threads::Bool=true)
unstack(df::AbstractDataFrame;
        renamecols::Function=identity, allowmissing::Bool=false,
        combine=only, fill=missing, threads::Bool=true)

Отменяет наложение фрейма данных df, т. е. преобразует его из длинного формата в широкий.

Ключи строк и столбцов упорядочиваются в порядке их первого появления.

Позиционные аргументы

  • df: AbstractDataFrame, для которого будет отменено наложение

  • rowkeys: столбцы с уникальным ключом для каждой строки. Если не задан, поиск ключа осуществляется путем группировки по всему, что не является colkey или value. Это может быть любой селектор столбцов (символ (Symbol), строка или целое число; :, Cols, All, Between, Not, регулярное выражение или вектор символов (Symbol), строк или целых чисел). Если rowkeys не содержит столбцов, предполагается, что все строки имеют одинаковый ключ.

  • colkey: столбец (Symbol, строка или целое число) содержащий имена столбцов в широком формате, по умолчанию имеет значение :variable.

  • values: столбец, хранящий значения (Symbol, строка или целое число), по умолчанию имеет значение :value.

Именованные аргументы

  • renamecols: функция, вызываемая для каждого уникального значения в colkey. Она должна возвращать имя создаваемого столбца (обычно в виде строки или Symbol). Дубликаты в результирующих именах при преобразовании в Symbolне допускаются. По умолчанию преобразования не выполняются.

  • allowmissing: если false (по умолчанию), возникает ошибка, если colkey содержит значения missing. Если true, создается столбец, ссылающийся на отсутствующее (missing) значение.

  • combine: если only (по умолчанию), возникает ошибка, если сочетание rowkeys и colkey содержит повторяющиеся записи. В противном случае передаваемое значение должно быть функцией, которая вызывается для представления вектора, содержащего все элементы для каждого сочетания rowkeys и colkey, присутствующих в данных.

  • fill: этим значением заполняются сочетания отсутствующих строк или столбцов. Аргумент по умолчанию — missing. Если столбец value является CategoricalVector и fill не задано значение missing, то, чтобы неналоженные столбцы значений также являлись CategoricalVector, fill должен быть передан как CategoricalValue.

  • threads: может ли функция combine выполняться в отдельных задачах, которые могут выполняться параллельно (возможно, с применением к нескольким строкам или группам одновременно). Тот момент, порождаются ли задачи, и их количество определяется автоматически. Задано значение false, если для combine требуется последовательное выполнение или он не является потокобезопасным.

Метаданные: метаданные на уровне таблиц в стиле :note и метаданные на уровне столбцов в стиле :note для столбцов ключей строк сохраняются.

Нерекомендуемые аргументы

  • Именованный аргумент allowduplicates устарел. Вместо него следует использовать именованный аргумент combine. Эквивалентом allowduplicates=true является combine=last, а эквивалентом allowduplicates=false — combine=only (по умолчанию).

Примеры

julia> wide = DataFrame(id=1:6,
                        a=repeat(1:3, inner=2),
                        b=repeat(1.0:2.0, inner=3),
                        c=repeat(1.0:1.0, inner=6),
                        d=repeat(1.0:3.0, inner=2))
6×5 DataFrame
 Row │ id     a      b        c        d
     │ Int64  Int64  Float64  Float64  Float64
─────┼─────────────────────────────────────────
   1 │     1      1      1.0      1.0      1.0
   2 │     2      1      1.0      1.0      1.0
   3 │     3      2      1.0      1.0      2.0
   4 │     4      2      2.0      1.0      2.0
   5 │     5      3      2.0      1.0      3.0
   6 │     6      3      2.0      1.0      3.0

julia> long = stack(wide)
18×4 DataFrame
 Row │ id     a      variable  value
     │ Int64  Int64  String    Float64
─────┼─────────────────────────────────
   1 │     1      1  b             1.0
   2 │     2      1  b             1.0
   3 │     3      2  b             1.0
   4 │     4      2  b             2.0
   5 │     5      3  b             2.0
   6 │     6      3  b             2.0
   7 │     1      1  c             1.0
   8 │     2      1  c             1.0
  ⋮  │   ⋮      ⋮       ⋮         ⋮
  12 │     6      3  c             1.0
  13 │     1      1  d             1.0
  14 │     2      1  d             1.0
  15 │     3      2  d             2.0
  16 │     4      2  d             2.0
  17 │     5      3  d             3.0
  18 │     6      3  d             3.0
                         3 rows omitted

julia> unstack(long)
6×5 DataFrame
 Row │ id     a      b         c         d
     │ Int64  Int64  Float64?  Float64?  Float64?
─────┼────────────────────────────────────────────
   1 │     1      1       1.0       1.0       1.0
   2 │     2      1       1.0       1.0       1.0
   3 │     3      2       1.0       1.0       2.0
   4 │     4      2       2.0       1.0       2.0
   5 │     5      3       2.0       1.0       3.0
   6 │     6      3       2.0       1.0       3.0

julia> unstack(long, :variable, :value)
6×5 DataFrame
 Row │ id     a      b         c         d
     │ Int64  Int64  Float64?  Float64?  Float64?
─────┼────────────────────────────────────────────
   1 │     1      1       1.0       1.0       1.0
   2 │     2      1       1.0       1.0       1.0
   3 │     3      2       1.0       1.0       2.0
   4 │     4      2       2.0       1.0       2.0
   5 │     5      3       2.0       1.0       3.0
   6 │     6      3       2.0       1.0       3.0

julia> unstack(long, :id, :variable, :value)
6×4 DataFrame
 Row │ id     b         c         d
     │ Int64  Float64?  Float64?  Float64?
─────┼─────────────────────────────────────
   1 │     1       1.0       1.0       1.0
   2 │     2       1.0       1.0       1.0
   3 │     3       1.0       1.0       2.0
   4 │     4       2.0       1.0       2.0
   5 │     5       2.0       1.0       3.0
   6 │     6       2.0       1.0       3.0

julia> unstack(long, [:id, :a], :variable, :value)
6×5 DataFrame
 Row │ id     a      b         c         d
     │ Int64  Int64  Float64?  Float64?  Float64?
─────┼────────────────────────────────────────────
   1 │     1      1       1.0       1.0       1.0
   2 │     2      1       1.0       1.0       1.0
   3 │     3      2       1.0       1.0       2.0
   4 │     4      2       2.0       1.0       2.0
   5 │     5      3       2.0       1.0       3.0
   6 │     6      3       2.0       1.0       3.0

julia> unstack(long, :id, :variable, :value, renamecols=x->Symbol(:_, x))
6×4 DataFrame
 Row │ id     _b        _c        _d
     │ Int64  Float64?  Float64?  Float64?
─────┼─────────────────────────────────────
   1 │     1       1.0       1.0       1.0
   2 │     2       1.0       1.0       1.0
   3 │     3       1.0       1.0       2.0
   4 │     4       2.0       1.0       2.0
   5 │     5       2.0       1.0       3.0
   6 │     6       2.0       1.0       3.0

Обратите внимание, что между приведенными выше расширенными результатами есть некоторые различия.

julia> df = DataFrame(id=["1", "1", "2"],
                      variable=["Var1", "Var2", "Var1"],
                      value=[1, 2, 3])
3×3 DataFrame
 Row │ id      variable  value
     │ String  String    Int64
─────┼─────────────────────────
   1 │ 1       Var1          1
   2 │ 1       Var2          2
   3 │ 2       Var1          3

julia> unstack(df, :variable, :value, fill=0)
2×3 DataFrame
 Row │ id      Var1   Var2
     │ String  Int64  Int64
─────┼──────────────────────
   1 │ 1           1      2
   2 │ 2           3      0

julia> df = DataFrame(cols=["a", "a", "b"], values=[1, 2, 4])
3×2 DataFrame
 Row │ cols    values
     │ String  Int64
─────┼────────────────
   1 │ a            1
   2 │ a            2
   3 │ b            4

julia> unstack(df, :cols, :values, combine=copy)
1×2 DataFrame
 Row │ a        b
     │ Array…?  Array…?
─────┼──────────────────
   1 │ [1, 2]   [4]

julia> unstack(df, :cols, :values, combine=sum)
1×2 DataFrame
 Row │ a       b
     │ Int64?  Int64?
─────┼────────────────
   1 │      3       4

# Base.permutedimsFunction

permutedims(df::AbstractDataFrame,
            [src_namescol::Union{Int, Symbol, AbstractString}],
            [dest_namescol::Union{Symbol, AbstractString}];
            makeunique::Bool=false, strict::Bool=true)

Поворачивает df на бок, чтобы строки стали столбцами, а значения в столбце, проиндексированном с помощью src_namescol, стали именами новых столбцов. В результирующем DataFrame имена столбцов df станут первым столбцом с именем, указанным с помощью dest_namescol.

Аргументы

  • df: AbstractDataFrame

  • src_namescol: столбец, который станет первым заголовком. Если не указан, имена столбцов :x1, :x2 и т. д. генерируются автоматически.

  • dest_namescol: имя первого столбца в возвращаемом DataFrame. По умолчанию используется то же имя, что и у src_namescol. Не поддерживается, если src_namescol является вектором или опущен.

  • makeunique: если задано значение false (по умолчанию), возникает ошибка при обнаружении повторяющихся имен; если задано значение true, к повторяющимся именам добавляется суффикс _i (i, начиная с 1 для первого повторяющегося имени). Не поддерживается, если src_namescol опущен.

  • strict: если задано значение true (по умолчанию), возникает ошибка, если все значения, содержащиеся в src_namescol, не являются Symbol или все являются AbstractString либо могут быть преобразованы в String с помощью convert. Если false все значения принимаются и будут изменены в строки с помощью функции string. Не поддерживается, если src_namescol является вектором или опущен.

Примечание. Типы элементов столбцов в результирующем DataFrame (кроме первого столбца, если он создан из имен столбцов df, который всегда имеет тип элемента String) будут зависеть от типов элементов всех входных столбцов на основе результата promote_type. То есть если исходный фрейм данных содержит столбцы Int и Float64, результирующие столбцы будут иметь тип элемента Float64. Если в источнике есть столбцы Int и String, результирующие столбцы будут иметь тип элемента Any.

Метаданные: метаданные на уровне таблиц в стиле :note сохраняются, а метаданные на уровне столбцов удаляются.

Примеры

julia> df = DataFrame(a=1:2, b=3:4)
2×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      3
   2 │     2      4

julia> permutedims(df)
2×2 DataFrame
 Row │ x1     x2
     │ Int64  Int64
─────┼──────────────
   1 │     1      2
   2 │     3      4

julia> permutedims(df, [:p, :q])
2×2 DataFrame
 Row │ p      q
     │ Int64  Int64
─────┼──────────────
   1 │     1      2
   2 │     3      4

julia> df1 = DataFrame(a=["x", "y"], b=[1.0, 2.0], c=[3, 4], d=[true, false])
2×4 DataFrame
 Row │ a       b        c      d
     │ String  Float64  Int64  Bool
─────┼───────────────────────────────
   1 │ x           1.0      3   true
   2 │ y           2.0      4  false

julia> permutedims(df1, 1) # запомните типы столбцов
3×3 DataFrame
 Row │ a       x        y
     │ String  Float64  Float64
─────┼──────────────────────────
   1 │ b           1.0      2.0
   2 │ c           3.0      4.0
   3 │ d           1.0      0.0

julia> df2 = DataFrame(a=["x", "y"], b=[1, "two"], c=[3, 4], d=[true, false])
2×4 DataFrame
 Row │ a       b    c      d
     │ String  Any  Int64  Bool
─────┼───────────────────────────
   1 │ x       1        3   true
   2 │ y       two      4  false

julia> permutedims(df2, 1, "different_name")
3×3 DataFrame
 Row │ different_name  x     y
     │ String          Any   Any
─────┼─────────────────────────────
   1 │ b               1     two
   2 │ c               3     4
   3 │ d               true  false

Сортировка

# Base.issortedFunction

issorted(df::AbstractDataFrame, cols=All();
         lt::Union{Function, AbstractVector{<:Function}}=isless,
         by::Union{Function, AbstractVector{<:Function}}=identity,
         rev::Union{Bool, AbstractVector{Bool}}=false,
         order::Union{Ordering, AbstractVector{<:Ordering}}=Forward,
         checkunique::Bool=false)

Проверяет, отсортирован ли фрейм данных df по столбцам cols. Проверка сортировки по нескольким столбцам выполняется лексикографически.

cols может представлять собой любой селектор столбцов (символ (Symbol), строку или целое число; :, Cols, All, Between, Not, регулярное выражение или вектор символов (Symbol), строк или целых чисел). Если cols не выбирает столбцы, проверьте, сортируется ли df по всем столбцам (это поведение устарело и будет изменено в будущих версиях).

Если rev имеет значение true, выполняется обратная сортировка. Чтобы включить обратную сортировку только для некоторых столбцов, передайте order(c, rev=true) в cols, где c соответствует индексу столбца (см. пример ниже).

Поскольку при наличии повторяющихся элементов допустимы несколько порядков сортировки, ключевое слово checkunique позволяет обнаруживать подобные ситуации. Если checkunique является true и найдены повторяющиеся элементы, возникнет ошибка. Использование ключевого слова checkunique поддерживается, только если не используются ключевые слова by и lt . Аналогично, использование предложений order(...), которые задают by или lt, не поддерживается, но допускается указание rev .

С помощью ключевого слова by можно задать функцию, которая будет применяться к каждому элементу перед сравнением. С помощью ключевого слова lt можно указать пользовательскую функцию «меньше чем». Если указать и by, и lt, функция lt применяется к результату функции by.

Именованные аргументы, указывающие порядок сортировки (rev, lt или by) могут представлять собой одно значение или вектор длиной, равной количеству столбцов, с которыми выполняется операция. Если передается одно значение, оно применяется ко всем столбцам. Если передается вектор, каждая запись применяется к столбцу в соответствующей позиции в cols.

Примеры

julia> df = DataFrame(a=[1, 2, 3, 4], b=[4, 3, 2, 1])
4×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      4
   2 │     2      3
   3 │     3      2
   4 │     4      1

julia> issorted(df)
true

julia> issorted(df, :a)
true

julia> issorted(df, :b)
false

julia> issorted(df, :b, rev=true)
true

# DataFrames.orderFunction

order(col::ColumnIndex; kwargs...)

Задает порядок сортировки для столбца col во фрейме данных. kwargs могут быть lt, by, rev и order со значениями, соответствующими правилам, определенным в sort!.

См. также описание sort!, sort

Примеры

julia> df = DataFrame(x=[-3, -1, 0, 2, 4], y=1:5)
5×2 DataFrame
 Row │ x      y
     │ Int64  Int64
─────┼──────────────
   1 │    -3      1
   2 │    -1      2
   3 │     0      3
   4 │     2      4
   5 │     4      5

julia> sort(df, order(:x, rev=true))
5×2 DataFrame
 Row │ x      y
     │ Int64  Int64
─────┼──────────────
   1 │     4      5
   2 │     2      4
   3 │     0      3
   4 │    -1      2
   5 │    -3      1

julia> sort(df, order(:x, by=abs))
5×2 DataFrame
 Row │ x      y
     │ Int64  Int64
─────┼──────────────
   1 │     0      3
   2 │    -1      2
   3 │     2      4
   4 │    -3      1
   5 │     4      5

# Base.sortFunction

sort(df::AbstractDataFrame, cols=All();
     alg::Union{Algorithm, Nothing}=nothing,
     lt::Union{Function, AbstractVector{<:Function}}=isless,
     by::Union{Function, AbstractVector{<:Function}}=identity,
     rev::Union{Bool, AbstractVector{Bool}}=false,
     order::Union{Ordering, AbstractVector{<:Ordering}}=Forward,
     view::Bool=false,
     checkunique::Bool=false)

Возвращает фрейм данных, содержащий строки в df, отсортированном по столбцам cols. Сортировка по нескольким столбцам выполняется лексикографически.

cols может представлять собой любой селектор столбцов (символ (Symbol), строку или целое число; :, Cols, All, Between, Not, регулярное выражение или вектор символов (Symbol), строк или целых чисел). Если cols не выбирает столбцы, сортирует df по всем столбцам (это поведение устарело и будет изменено в будущих версиях).

Если rev имеет значение true, выполняется обратная сортировка. Чтобы включить обратную сортировку только для некоторых столбцов, передайте order(c, rev=true) в cols, где c соответствует индексу столбца (см. пример ниже).

Поскольку при наличии повторяющихся элементов допустимы несколько порядков сортировки, ключевое слово checkunique позволяет обнаруживать подобные ситуации. Если checkunique является true и найдены повторяющиеся элементы, возникнет ошибка. Использование ключевого слова checkunique поддерживается, только если не используются ключевые слова by и lt . Аналогично, использование предложений order(...), которые задают by или lt, не поддерживается, но допускается указание rev .

С помощью ключевого слова by можно задать функцию, которая будет применяться к каждому элементу перед сравнением. С помощью ключевого слова lt можно указать пользовательскую функцию «меньше чем». Если указать и by, и lt, функция lt применяется к результату функции by.

Именованные аргументы, указывающие порядок сортировки (rev, lt или by) могут представлять собой одно значение или вектор длиной, равной количеству столбцов, с которыми выполняется операция. Если передается одно значение, оно применяется ко всем столбцам. Если передается вектор, каждая запись применяется к столбцу в соответствующей позиции в cols.

Если alg имеет значение nothing (по умолчанию), наиболее подходящий алгоритм выбирается автоматически среди TimSort, MergeSort и RadixSort в зависимости от типа сортирующих столбцов и количества строк в df.

Если view=false, возвращается только что выделенный DataFrame. Если view=true, возвращается представление SubDataFrame для df.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Примеры

julia> df = DataFrame(x=[3, 1, 2, 1], y=["b", "c", "a", "b"])
4×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     3  b
   2 │     1  c
   3 │     2  a
   4 │     1  b

julia> sort(df, :x)
4×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     1  c
   2 │     1  b
   3 │     2  a
   4 │     3  b

julia> sort(df, [:x, :y])
4×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     1  b
   2 │     1  c
   3 │     2  a
   4 │     3  b

julia> sort(df, [:x, :y], rev=true)
4×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     3  b
   2 │     2  a
   3 │     1  c
   4 │     1  b

julia> sort(df, [:x, order(:y, rev=true)])
4×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     1  c
   2 │     1  b
   3 │     2  a
   4 │     3  b

# Base.sort!Function

sort!(df::AbstractDataFrame, cols=All();
      alg::Union{Algorithm, Nothing}=nothing,
      lt::Union{Function, AbstractVector{<:Function}}=isless,
      by::Union{Function, AbstractVector{<:Function}}=identity,
      rev::Union{Bool, AbstractVector{Bool}}=false,
      order::Union{Ordering, AbstractVector{<:Ordering}}=Forward,
      checkunique::Bool=false)

Сортирует фрейм данных df по столбцам cols, переставляя его строки на месте. Сортировка по нескольким столбцам выполняется лексикографически.

cols может представлять собой любой селектор столбцов (символ (Symbol), строку или целое число; :, Cols, All, Between, Not, регулярное выражение или вектор символов (Symbol), строк или целых чисел). Если cols не выбирает столбцы, сортирует df по всем столбцам (это поведение устарело и будет изменено в будущих версиях).

Если rev имеет значение true, выполняется обратная сортировка. Чтобы включить обратную сортировку только для некоторых столбцов, передайте order(c, rev=true) в cols, где c соответствует индексу столбца (см. пример ниже).

Поскольку при наличии повторяющихся элементов допустимы несколько порядков сортировки, ключевое слово checkunique позволяет обнаруживать подобные ситуации. Если checkunique является true и найдены повторяющиеся элементы, возникнет ошибка. Использование ключевого слова checkunique поддерживается, только если не используются ключевые слова by и lt . Аналогично, использование предложений order(...), которые задают by или lt, не поддерживается, но допускается указание rev .

С помощью ключевого слова by можно задать функцию, которая будет применяться к каждому элементу перед сравнением. С помощью ключевого слова lt можно указать пользовательскую функцию «меньше чем». Если указать и by, и lt, функция lt применяется к результату функции by.

Именованные аргументы, указывающие порядок сортировки (rev, lt или by) могут представлять собой одно значение или вектор длиной, равной количеству столбцов, с которыми выполняется операция. Если передается одно значение, оно применяется ко всем столбцам. Если передается вектор, каждая запись применяется к столбцу в соответствующей позиции в cols.

Если alg имеет значение nothing (по умолчанию), наиболее подходящий алгоритм выбирается автоматически среди TimSort, MergeSort и RadixSort в зависимости от типа сортирующих столбцов и количества строк в df.

sort! выдаст корректный результат, даже если некоторые столбцы переданного фрейма данных идентичны (проверены с помощью ===). В противном случае, если два столбца имеют общую часть памяти, но не идентичны (например, являются разными представлениями одного и того же родительского вектора), результат sort! может быть неверным.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Метаданные, имеющие другие стили, удаляются (из родительского фрейма данных, если df является SubDataFrame).

Примеры

julia> df = DataFrame(x=[3, 1, 2, 1], y=["b", "c", "a", "b"])
4×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     3  b
   2 │     1  c
   3 │     2  a
   4 │     1  b

julia> sort!(df, :x)
4×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     1  c
   2 │     1  b
   3 │     2  a
   4 │     3  b

julia> sort!(df, [:x, :y])
4×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     1  b
   2 │     1  c
   3 │     2  a
   4 │     3  b

julia> sort!(df, [:x, :y], rev=true)
4×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     3  b
   2 │     2  a
   3 │     1  c
   4 │     1  b

julia> sort!(df, [:x, order(:y, rev=true)])
4×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     1  c
   2 │     1  b
   3 │     2  a
   4 │     3  b

# Base.sortpermFunction

sortperm(df::AbstractDataFrame, cols=All();
         alg::Union{Algorithm, Nothing}=nothing,
         lt::Union{Function, AbstractVector{<:Function}}=isless,
         by::Union{Function, AbstractVector{<:Function}}=identity,
         rev::Union{Bool, AbstractVector{Bool}}=false,
         order::Union{Ordering, AbstractVector{<:Ordering}}=Forward,
         checkunique::Bool=false)

Возвращает вектор перестановки индексов строк фрейма данных df, который располагает их в отсортированном порядке в соответствии со столбцами cols. Упорядочение по нескольким столбцам выполняется лексикографически.

cols может представлять собой любой селектор столбцов (символ (Symbol), строку или целое число; :, Cols, All, Between, Not, регулярное выражение или вектор символов (Symbol), строк или целых чисел). Если cols не выбирает ни одного столбца, возвращается вектор перестановок, основанный на сортировке всех столбцов (это поведение устарело и будет изменено в будущих версиях).

Если rev имеет значение true, выполняется обратная сортировка. Чтобы включить обратную сортировку только для некоторых столбцов, передайте order(c, rev=true) в cols, где c соответствует индексу столбца (см. пример ниже).

Поскольку при наличии повторяющихся элементов допустимы несколько порядков сортировки, ключевое слово checkunique позволяет обнаруживать подобные ситуации. Если checkunique является true и найдены повторяющиеся элементы, возникнет ошибка. Использование ключевого слова checkunique поддерживается, только если не используются ключевые слова by и lt . Аналогично, использование предложений order(...), которые задают by или lt, не поддерживается, но допускается указание rev .

С помощью ключевого слова by можно задать функцию, которая будет применяться к каждому элементу перед сравнением. С помощью ключевого слова lt можно указать пользовательскую функцию «меньше чем». Если указать и by, и lt, функция lt применяется к результату функции by.

Именованные аргументы, указывающие порядок сортировки (rev, lt или by) могут представлять собой одно значение или вектор длиной, равной количеству столбцов, с которыми выполняется операция. Если передается одно значение, оно применяется ко всем столбцам. Если передается вектор, каждая запись применяется к столбцу в соответствующей позиции в cols.

Если alg имеет значение nothing (по умолчанию), наиболее подходящий алгоритм выбирается автоматически среди TimSort, MergeSort и RadixSort в зависимости от типа сортирующих столбцов и количества строк в df.

Примеры

julia> df = DataFrame(x=[3, 1, 2, 1], y=["b", "c", "a", "b"])
4×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     3  b
   2 │     1  c
   3 │     2  a
   4 │     1  b

julia> sortperm(df, :x)
4-element Vector{Int64}:
 2
 4
 3
 1

julia> sortperm(df, [:x, :y])
4-element Vector{Int64}:
 4
 2
 3
 1

julia> sortperm(df, [:x, :y], rev=true)
4-element Vector{Int64}:
 1
 3
 2
 4

julia> sortperm(df, [:x, order(:y, rev=true)])
4-element Vector{Int64}:
 2
 4
 3
 1

Объединение

# DataAPI.antijoinFunction

antijoin(df1, df2; on, makeunique=false, validate=(false, false), matchmissing=:error)

Выполняет антисоединение двух объектов фрейма данных и возвращает DataFrame, содержащий результат. Антисоединение возвращает подмножество строк df1, которые не совпадают с ключами в df2.

Порядок строк в результате сохраняется из df1.

Аргументы

  • df1, df2: соединяемые AbstractDataFrames

Именованные аргументы

  • on: имена ключевых столбцов, по которым следует соединить фреймы данных. Это может быть одно имя или вектор имен (для соединения по нескольким столбцам). Вместо имени можно использовать пару имен left=>right в случае, когда ключ имеет разные имена в df1 и df2 (разрешается смешивать имена и пары имен в векторе). Значения ключей сравниваются с помощью isequal. on является обязательным аргументом.

  • makeunique: игнорируется, так как столбцы не добавляются к столбцам df1 (он предоставляется для согласованности с другими функциями).

  • validate: следует ли проверять, что столбцы, переданные в качестве аргумента on, определяют уникальные ключи в каждом входном фрейме данных (в соответствии с isequal). Может быть кортежем или парой, первый элемент которой указывает, запускать ли проверку для df1, а второй — для df2. По умолчанию проверка не выполняется.

  • matchmissing: если имеет значение :error, возникает ошибка, если missing присутствует в столбцах on; если имеет значение :equal, missing разрешено и отсутствующие значения сопоставляются; если имеет значение :notequal, отсутствующие значения удаляются в столбцах on df2.

Не допускается соединение по столбцам, содержащим NaN или -0.0 в вещественной или мнимой частях числа. Чтобы выполнить соединение по таким значениям, используйте CategoricalArrays.jl и преобразуйте столбец, содержащий такие значения, в CategoricalVector.

При объединении категориальных столбцов on, отличающихся упорядочением уровней, упорядочение левого фрейма данных имеет приоритет над упорядочением правого фрейма данных.

Метаданные: метаданные на уровне таблиц и метаданные на уровне столбцов в стиле :note принимаются из df1.

См. также описание innerjoin, leftjoin, rightjoin, outerjoin, semijoin, crossjoin.

Примеры

julia> name = DataFrame(ID=[1, 2, 3], Name=["John Doe", "Jane Doe", "Joe Blogs"])
3×2 DataFrame
 Row │ ID     Name
     │ Int64  String
─────┼──────────────────
   1 │     1  John Doe
   2 │     2  Jane Doe
   3 │     3  Joe Blogs

julia> job = DataFrame(ID=[1, 2, 4], Job=["Lawyer", "Doctor", "Farmer"])
3×2 DataFrame
 Row │ ID     Job
     │ Int64  String
─────┼───────────────
   1 │     1  Lawyer
   2 │     2  Doctor
   3 │     4  Farmer

julia> antijoin(name, job, on = :ID)
1×2 DataFrame
 Row │ ID     Name
     │ Int64  String
─────┼──────────────────
   1 │     3  Joe Blogs

julia> job2 = DataFrame(identifier=[1, 2, 4], Job=["Lawyer", "Doctor", "Farmer"])
3×2 DataFrame
 Row │ identifier  Job
     │ Int64       String
─────┼────────────────────
   1 │          1  Lawyer
   2 │          2  Doctor
   3 │          4  Farmer

julia> antijoin(name, job2, on = :ID => :identifier)
1×2 DataFrame
 Row │ ID     Name
     │ Int64  String
─────┼──────────────────
   1 │     3  Joe Blogs

julia> antijoin(name, job2, on = [:ID => :identifier])
1×2 DataFrame
 Row │ ID     Name
     │ Int64  String
─────┼──────────────────
   1 │     3  Joe Blogs

# DataAPI.crossjoinFunction

crossjoin(df1::AbstractDataFrame, df2::AbstractDataFrame;
          makeunique::Bool=false, renamecols=identity => identity)
crossjoin(df1, df2, dfs...; makeunique = false)

Выполняет перекрестное соединение двух или более объектов фрейма данных и возвращает DataFrame, содержащий результат. Перекрестное соединение возвращает декартово произведение строк из всех переданных фреймов данных, где первый переданный фрейм данных присваивается измерению, которое изменяется медленнее всего, а последний фрейм данных присваивается измерению, которое изменяется быстрее всего.

Аргументы

  • df1, df2, dfs...: соединяемые AbstractDataFrames

Именованные аргументы

  • makeunique: если задано значение false (по умолчанию), возникает ошибка при обнаружении повторяющихся имен в столбцах, по которым не выполнено соединение; если задано значение true, к повторяющимся именам добавляется суффикс _i, (i, начиная с 1 для первого повторяющегося имени).

  • renamecols: пара (Pair), указывающая, как должны быть переименованы столбцы левого и правого фреймов данных в результирующем фрейме данных. Каждый элемент пары может представлять собой строку, или может быть передан символ (Symbol), в этом случае он добавляется к исходному имени столбца. В качестве альтернативы можно передать функцию, в этом случае она применяется к каждому имени столбца, которое передается ей в виде строки (String).

Если передается более двух фреймов данных, соединение выполняется рекурсивно с левой ассоциативностью.

Метаданные: метаданные на уровне таблиц в стиле :note сохраняются только для ключей, которые определены во всех передаваемых таблицах и имеют одинаковое значение. Метаданные на уровне столбцов в стиле :note сохраняются из обеих таблиц.

См. также описание innerjoin, leftjoin, rightjoin, outerjoin, semijoin, antijoin.

Примеры

julia> df1 = DataFrame(X=1:3)
3×1 DataFrame
 Row │ X
     │ Int64
─────┼───────
   1 │     1
   2 │     2
   3 │     3

julia> df2 = DataFrame(Y=["a", "b"])
2×1 DataFrame
 Row │ Y
     │ String
─────┼────────
   1 │ a
   2 │ b

julia> crossjoin(df1, df2)
6×2 DataFrame
 Row │ X      Y
     │ Int64  String
─────┼───────────────
   1 │     1  a
   2 │     1  b
   3 │     2  a
   4 │     2  b
   5 │     3  a
   6 │     3  b

# DataAPI.innerjoinFunction

innerjoin(df1, df2; on, makeunique=false, validate=(false, false),
          renamecols=(identity => identity), matchmissing=:error,
          order=:undefined)
innerjoin(df1, df2, dfs...; on, makeunique=false,
          validate=(false, false), matchmissing=:error,
          order=:undefined)

Выполняет внутреннее соединение двух или более объектов фрейма данных и возвращает DataFrame, содержащий результат. Внутреннее соединение включает строки с ключами, которые совпадают во всех переданных фреймах данных.

В возвращаемом фрейме данных тип столбцов, по которым соединяются фреймы данных, определяется типом этих столбцов в df1. Такое поведение может измениться в будущих выпусках.

Аргументы

  • df1, df2, dfs...: соединяемые AbstractDataFrames

Именованные аргументы

  • on: имена ключевых столбцов, по которым следует соединить фреймы данных. Это может быть одно имя или вектор имен (для соединения по нескольким столбцам). При соединении только двух фреймов данных вместо имени можно использовать пару имен left=>right в случае, кода когда ключ имеет разные имена в df1 и df2 (разрешено смешивать имена и пары имен в векторе). Значения ключей сравниваются с помощью isequal. on является обязательным аргументом.

  • makeunique: если задано значение false (по умолчанию), возникает ошибка при обнаружении повторяющихся имен в столбцах, по которым не выполнено соединение; если задано значение true, к повторяющимся именам добавляется суффикс _i, (i, начиная с 1 для первого повторяющегося имени).

  • validate: следует ли проверять, что столбцы, переданные в качестве аргумента on, определяют уникальные ключи в каждом входном фрейме данных (в соответствии с isequal). Может быть кортежем или парой, первый элемент которой указывает, запускать ли проверку для df1, а второй — для df2. По умолчанию проверка не выполняется.

  • renamecols: пара (Pair), указывающая, как должны быть переименованы столбцы левого и правого фреймов данных в результирующем фрейме данных. Каждый элемент пары может представлять собой строку, или может быть передан символ (Symbol), в этом случае он добавляется к исходному имени столбца. В качестве альтернативы можно передать функцию, в этом случае она применяется к каждому имени столбца, которое передается ей в виде строки (String). Обратите внимание, что renamecols не влияет на столбцы on, имена которых всегда берутся из левого фрейма данных и остаются неизменными.

  • matchmissing: если имеет значение :error, возникает ошибка, если missing присутствует в столбцах on; если имеет значение :equal, missing разрешено и отсутствующие значения сопоставляются; если имеет значение :notequal, отсутствующие значения удаляются в столбцах df1 и df2 on.

  • order: если :undefined (по умолчанию), порядок строк в результате не определен и может измениться в будущих выпусках. Если :left, сохраняется порядок строк из левого фрейма данных. Если :right, сохраняется порядок строк из правого фрейма данных.

Не допускается соединение по столбцам, содержащим NaN или -0.0 в вещественной или мнимой частях числа. Чтобы выполнить соединение по таким значениям, используйте CategoricalArrays.jl и преобразуйте столбец, содержащий такие значения, в CategoricalVector.

При объединении категориальных столбцов on, отличающихся упорядочением уровней, упорядочение левого фрейма данных имеет приоритет над упорядочением правого фрейма данных.

Если передается более двух фреймов данных, соединение выполняется рекурсивно с левой ассоциативностью. В этом случае именованный аргумент validate применяется рекурсивно с левой ассоциативностью.

Метаданные: метаданные на уровне таблиц в стиле :note и метаданные на уровне столбцов в стиле :note для столбцов ключей сохраняются только для ключей, которые определены во всех передаваемых таблицах и имеют одинаковое значение. Метаданные на уровне столбцов в стиле :note сохраняются для всех остальных столбцов.

См. также описание leftjoin, rightjoin, outerjoin, semijoin, antijoin, crossjoin.

Примеры

julia> name = DataFrame(ID=[1, 2, 3], Name=["John Doe", "Jane Doe", "Joe Blogs"])
3×2 DataFrame
 Row │ ID     Name
     │ Int64  String
─────┼──────────────────
   1 │     1  John Doe
   2 │     2  Jane Doe
   3 │     3  Joe Blogs

julia> job = DataFrame(ID=[1, 2, 4], Job=["Lawyer", "Doctor", "Farmer"])
3×2 DataFrame
 Row │ ID     Job
     │ Int64  String
─────┼───────────────
   1 │     1  Lawyer
   2 │     2  Doctor
   3 │     4  Farmer

julia> innerjoin(name, job, on = :ID)
2×3 DataFrame
 Row │ ID     Name      Job
     │ Int64  String    String
─────┼─────────────────────────
   1 │     1  John Doe  Lawyer
   2 │     2  Jane Doe  Doctor

julia> job2 = DataFrame(identifier=[1, 2, 4], Job=["Lawyer", "Doctor", "Farmer"])
3×2 DataFrame
 Row │ identifier  Job
     │ Int64       String
─────┼────────────────────
   1 │          1  Lawyer
   2 │          2  Doctor
   3 │          4  Farmer

julia> innerjoin(name, job2, on = :ID => :identifier, renamecols = "_left" => "_right")
2×3 DataFrame
 Row │ ID     Name_left  Job_right
     │ Int64  String     String
─────┼─────────────────────────────
   1 │     1  John Doe   Lawyer
   2 │     2  Jane Doe   Doctor

julia> innerjoin(name, job2, on = [:ID => :identifier], renamecols = uppercase => lowercase)
2×3 DataFrame
 Row │ ID     NAME      job
     │ Int64  String    String
─────┼─────────────────────────
   1 │     1  John Doe  Lawyer
   2 │     2  Jane Doe  Doctor

# DataAPI.leftjoinFunction

leftjoin(df1, df2; on, makeunique=false, source=nothing, validate=(false, false),
         renamecols=(identity => identity), matchmissing=:error, order=:undefined)

Выполняет левое соединение двух объектов фрейма данных и возвращает DataFrame, содержащий результат. Левое соединение включает все строки из df1.

В возвращаемом фрейме данных тип столбцов, по которым соединяются фреймы данных, определяется типом этих столбцов в df1. Такое поведение может измениться в будущих выпусках.

Аргументы

  • df1, df2: соединяемые AbstractDataFrames

Именованные аргументы

  • on: имена ключевых столбцов, по которым следует соединить фреймы данных. Это может быть одно имя или вектор имен (для соединения по нескольким столбцам). Вместо имени можно использовать пару имен left=>right в случае, когда ключ имеет разные имена в df1 и df2 (разрешается смешивать имена и пары имен в векторе). Значения ключей сравниваются с помощью isequal. on является обязательным аргументом.

  • makeunique: если задано значение false (по умолчанию), возникает ошибка при обнаружении повторяющихся имен в столбцах, по которым не выполнено соединение; если задано значение true, к повторяющимся именам добавляется суффикс _i, (i, начиная с 1 для первого повторяющегося имени).

  • source: значение по умолчанию — nothing. Если Symbol или строка, добавляет столбец указателя с заданным именем, чтобы определить, появилась ли строка только в df1 ("left_only") или в обоих ("both"). Если имя уже используется, имя столбца будет изменено, если makeunique=true.

  • validate: следует ли проверять, что столбцы, переданные в качестве аргумента on, определяют уникальные ключи в каждом входном фрейме данных (в соответствии с isequal). Может быть кортежем или парой, первый элемент которой указывает, запускать ли проверку для df1, а второй — для df2. По умолчанию проверка не выполняется.

  • renamecols: пара (Pair), указывающая, как должны быть переименованы столбцы левого и правого фреймов данных в результирующем фрейме данных. Каждый элемент пары может представлять собой строку, или может быть передан символ (Symbol), в этом случае он добавляется к исходному имени столбца. В качестве альтернативы можно передать функцию, в этом случае она применяется к каждому имени столбца, которое передается ей в виде строки (String). Обратите внимание, что renamecols не влияет на столбцы on, имена которых всегда берутся из левого фрейма данных и остаются неизменными.

  • matchmissing: если имеет значение :error, возникает ошибка, если missing присутствует в столбцах on; если имеет значение :equal, missing разрешено и отсутствующие значения сопоставляются; если имеет значение :notequal, отсутствующие значения удаляются в столбцах on df2.

  • order: если :undefined (по умолчанию), порядок строк в результате не определен и может измениться в будущих выпусках. Если :left, сохраняется порядок строк из левого фрейма данных. Если :right, сохраняется порядок строк строк из правого фрейма данных (несовпадающие строки помещаются в конец).

Все столбцы возвращаемого фрейма данных будут поддерживать отсутствующие значения.

Не допускается соединение по столбцам, содержащим NaN или -0.0 в вещественной или мнимой частях числа. Чтобы выполнить соединение по таким значениям, используйте CategoricalArrays.jl и преобразуйте столбец, содержащий такие значения, в CategoricalVector.

При объединении категориальных столбцов on, отличающихся упорядочением уровней, упорядочение левого фрейма данных имеет приоритет над упорядочением правого фрейма данных.

Метаданные: метаданные на уровне таблиц и метаданные на уровне столбцов в стиле :note принимаются из df1 (включая столбцы ключей), за исключением столбцов, добавленных в него из df2, метаданные на уровне столбцов в стиле :note которого принимаются из df2.

См. также описание innerjoin, rightjoin, outerjoin, semijoin, antijoin, crossjoin.

Примеры

julia> name = DataFrame(ID=[1, 2, 3], Name=["John Doe", "Jane Doe", "Joe Blogs"])
3×2 DataFrame
 Row │ ID     Name
     │ Int64  String
─────┼──────────────────
   1 │     1  John Doe
   2 │     2  Jane Doe
   3 │     3  Joe Blogs

julia> job = DataFrame(ID=[1, 2, 4], Job=["Lawyer", "Doctor", "Farmer"])
3×2 DataFrame
 Row │ ID     Job
     │ Int64  String
─────┼───────────────
   1 │     1  Lawyer
   2 │     2  Doctor
   3 │     4  Farmer

julia> leftjoin(name, job, on = :ID)
3×3 DataFrame
 Row │ ID     Name       Job
     │ Int64  String     String?
─────┼───────────────────────────
   1 │     1  John Doe   Lawyer
   2 │     2  Jane Doe   Doctor
   3 │     3  Joe Blogs  missing

julia> job2 = DataFrame(identifier=[1, 2, 4], Job=["Lawyer", "Doctor", "Farmer"])
3×2 DataFrame
 Row │ identifier  Job
     │ Int64       String
─────┼────────────────────
   1 │          1  Lawyer
   2 │          2  Doctor
   3 │          4  Farmer

julia> leftjoin(name, job2, on = :ID => :identifier, renamecols = "_left" => "_right")
3×3 DataFrame
 Row │ ID     Name_left  Job_right
     │ Int64  String     String?
─────┼─────────────────────────────
   1 │     1  John Doe   Lawyer
   2 │     2  Jane Doe   Doctor
   3 │     3  Joe Blogs  missing

julia> leftjoin(name, job2, on = [:ID => :identifier], renamecols = uppercase => lowercase)
3×3 DataFrame
 Row │ ID     NAME       job
     │ Int64  String     String?
─────┼───────────────────────────
   1 │     1  John Doe   Lawyer
   2 │     2  Jane Doe   Doctor
   3 │     3  Joe Blogs  missing

# DataFrames.leftjoin!Function

leftjoin!(df1, df2; on, makeunique=false, source=nothing,
          matchmissing=:error)

Выполняет левое соединение двух объектов фрейма данных, обновляя df1 присоединенными столбцами из df2.

Левое соединение включает все строки из df1 и не затрагивает все строки и столбцы из df1. . Обратите внимание, что каждая строка в df1 должна иметь не более одного совпадения в df2. В противном случае, эта функция не сможет выполнить соединение на месте, поскольку потребуется добавить новые строки в df1.

Аргументы

  • df1, df2: соединяемые AbstractDataFrames

Именованные аргументы

  • on: имена ключевых столбцов, по которым следует соединить фреймы данных. Это может быть одно имя или вектор имен (для соединения по нескольким столбцам). Вместо имени можно использовать пару имен left=>right в случае, когда ключ имеет разные имена в df1 и df2 (разрешается смешивать имена и пары имен в векторе). Значения ключей сравниваются с помощью isequal. on является обязательным аргументом.

  • makeunique: если задано значение false (по умолчанию), возникает ошибка при обнаружении повторяющихся имен в столбцах, по которым не выполнено соединение; если задано значение true, к повторяющимся именам добавляется суффикс _i, (i, начиная с 1 для первого повторяющегося имени).

  • source: значение по умолчанию — nothing. Если Symbol или строка, добавляет столбец указателя с заданным именем, чтобы определить, появилась ли строка только в df1 ("left_only") или в обоих ("both"). Если имя уже используется, имя столбца будет изменено, если makeunique=true.

  • matchmissing: если имеет значение :error, возникает ошибка, если missing присутствует в столбцах on; если имеет значение :equal, missing разрешено и отсутствующие значения сопоставляются; если имеет значение :notequal, отсутствующие значения удаляются в столбцах on df2.

Столбцы, добавленные в df1 из df2, будут поддерживать отсутствующие значения.

Не допускается соединение по столбцам, содержащим NaN или -0.0 в вещественной или мнимой частях числа. Чтобы выполнить соединение по таким значениям, используйте CategoricalArrays.jl и преобразуйте столбец, содержащий такие значения, в CategoricalVector.

Метаданные: метаданные на уровне таблиц и метаданные на уровне столбцов в стиле :note принимаются из df1 (включая столбцы ключей), за исключением столбцов, добавленных в него из df2, метаданные на уровне столбцов в стиле :note которого принимаются из df2.

См. также описание leftjoin.

Примеры

julia> name = DataFrame(ID=[1, 2, 3], Name=["John Doe", "Jane Doe", "Joe Blogs"])
3×2 DataFrame
 Row │ ID     Name
     │ Int64  String
─────┼──────────────────
   1 │     1  John Doe
   2 │     2  Jane Doe
   3 │     3  Joe Blogs

julia> job = DataFrame(ID=[1, 2, 4], Job=["Lawyer", "Doctor", "Farmer"])
3×2 DataFrame
 Row │ ID     Job
     │ Int64  String
─────┼───────────────
   1 │     1  Lawyer
   2 │     2  Doctor
   3 │     4  Farmer

julia> leftjoin!(name, job, on = :ID)
3×3 DataFrame
 Row │ ID     Name       Job
     │ Int64  String     String?
─────┼───────────────────────────
   1 │     1  John Doe   Lawyer
   2 │     2  Jane Doe   Doctor
   3 │     3  Joe Blogs  missing

julia> job2 = DataFrame(identifier=[1, 2, 4], Job=["Lawyer", "Doctor", "Farmer"])
3×2 DataFrame
 Row │ identifier  Job
     │ Int64       String
─────┼────────────────────
   1 │          1  Lawyer
   2 │          2  Doctor
   3 │          4  Farmer

julia> leftjoin!(name, job2, on = :ID => :identifier, makeunique=true, source=:source)
3×5 DataFrame
 Row │ ID     Name       Job      Job_1    source
     │ Int64  String     String?  String?  String
─────┼───────────────────────────────────────────────
   1 │     1  John Doe   Lawyer   Lawyer   both
   2 │     2  Jane Doe   Doctor   Doctor   both
   3 │     3  Joe Blogs  missing  missing  left_only

# DataAPI.outerjoinFunction

outerjoin(df1, df2; on, makeunique=false, source=nothing, validate=(false, false),
          renamecols=(identity => identity), matchmissing=:error, order=:undefined)
outerjoin(df1, df2, dfs...; on, makeunique = false,
          validate = (false, false), matchmissing=:error, order=:undefined)

Выполняет внешнее соединение двух или более объектов фрейма данных и возвращает DataFrame, содержащий результат. Внешнее соединение включает строки с ключами, которые появляются во всех переданных фреймах данных.

Порядок строк в результате не определен и может измениться в будущих выпусках.

В возвращаемом фрейме данных тип столбцов, по которым соединяются фреймы данных, определяется типом элемента этих столбцов в df1 и df2. Это поведение может измениться в будущих выпусках.

Аргументы

  • df1, df2, dfs...: соединяемые AbstractDataFrames

Именованные аргументы

  • on: имена ключевых столбцов, по которым следует соединить фреймы данных. Это может быть одно имя или вектор имен (для соединения по нескольким столбцам). При соединении только двух фреймов данных вместо имени можно использовать пару имен left=>right в случае, кода когда ключ имеет разные имена в df1 и df2 (разрешено смешивать имена и пары имен в векторе). Значения ключей сравниваются с помощью isequal. on является обязательным аргументом.

  • makeunique: если задано значение false (по умолчанию), возникает ошибка при обнаружении повторяющихся имен в столбцах, по которым не выполнено соединение; если задано значение true, к повторяющимся именам добавляется суффикс _i, (i, начиная с 1 для первого повторяющегося имени).

  • source: значение по умолчанию — nothing. Если Symbol или строка, добавляет столбец указателя с заданным именем, чтобы определить, появилась ли строка только в df1 ("left_only"), только в df2 ("right_only") или в обоих ("both"). Если имя уже используется, имя столбца будет изменено, если makeunique=true. Этот аргумент поддерживается только при соединении двух фреймов данных.

  • validate: следует ли проверять, что столбцы, переданные в качестве аргумента on, определяют уникальные ключи в каждом входном фрейме данных (в соответствии с isequal). Может быть кортежем или парой, первый элемент которой указывает, запускать ли проверку для df1, а второй — для df2. По умолчанию проверка не выполняется.

  • renamecols: пара (Pair), указывающая, как должны быть переименованы столбцы левого и правого фреймов данных в результирующем фрейме данных. Каждый элемент пары может представлять собой строку, или может быть передан символ (Symbol), в этом случае он добавляется к исходному имени столбца. В качестве альтернативы можно передать функцию, в этом случае она применяется к каждому имени столбца, которое передается ей в виде строки (String). Обратите внимание, что renamecols не влияет на столбцы on, имена которых всегда берутся из левого фрейма данных и остаются неизменными.

  • matchmissing: если имеет значение :error, возникает ошибка, если missing присутствует в столбцах on; если имеет значение :equal, missing разрешено и отсутствующие значения совпадают.

  • order: если :undefined (по умолчанию), порядок строк в результате не определен и может измениться в будущих выпусках. Если :left, сохраняется порядок строк из левого фрейма данных (несовпадающие строки помещаются в конец). Если :right, сохраняется порядок строк из правого фрейма данных. (несовпадающие строки помещаются в конец).

Все столбцы возвращаемого фрейма данных будут поддерживать отсутствующие значения.

Не допускается соединение по столбцам, содержащим NaN или -0.0 в вещественной или мнимой частях числа. Чтобы выполнить соединение по таким значениям, используйте CategoricalArrays.jl и преобразуйте столбец, содержащий такие значения, в CategoricalVector.

При объединении категориальных столбцов on, отличающихся упорядочением уровней, упорядочение левого фрейма данных имеет приоритет над упорядочением правого фрейма данных.

Если передается более двух фреймов данных, соединение выполняется рекурсивно с левой ассоциативностью. В этом случае именованный аргумент indicator не поддерживается, и именованный аргумент validate применяется рекурсивно с левой ассоциативностью.

Метаданные: метаданные на уровне таблиц в стиле :note и метаданные на уровне столбцов в стиле :note для столбцов ключей сохраняются только для ключей, которые определены во всех передаваемых таблицах и имеют одинаковое значение. Метаданные на уровне столбцов в стиле :note сохраняются для всех остальных столбцов.

См. также описание innerjoin, leftjoin, rightjoin, semijoin, antijoin, crossjoin.

Примеры

julia> name = DataFrame(ID=[1, 2, 3], Name=["John Doe", "Jane Doe", "Joe Blogs"])
3×2 DataFrame
 Row │ ID     Name
     │ Int64  String
─────┼──────────────────
   1 │     1  John Doe
   2 │     2  Jane Doe
   3 │     3  Joe Blogs

julia> job = DataFrame(ID=[1, 2, 4], Job=["Lawyer", "Doctor", "Farmer"])
3×2 DataFrame
 Row │ ID     Job
     │ Int64  String
─────┼───────────────
   1 │     1  Lawyer
   2 │     2  Doctor
   3 │     4  Farmer

julia> outerjoin(name, job, on = :ID)
4×3 DataFrame
 Row │ ID     Name       Job
     │ Int64  String?    String?
─────┼───────────────────────────
   1 │     1  John Doe   Lawyer
   2 │     2  Jane Doe   Doctor
   3 │     3  Joe Blogs  missing
   4 │     4  missing    Farmer

julia> job2 = DataFrame(identifier=[1, 2, 4], Job=["Lawyer", "Doctor", "Farmer"])
3×2 DataFrame
 Row │ identifier  Job
     │ Int64       String
─────┼────────────────────
   1 │          1  Lawyer
   2 │          2  Doctor
   3 │          4  Farmer

julia> outerjoin(name, job2, on = :ID => :identifier, renamecols = "_left" => "_right")
4×3 DataFrame
 Row │ ID     Name_left  Job_right
     │ Int64  String?    String?
─────┼─────────────────────────────
   1 │     1  John Doe   Lawyer
   2 │     2  Jane Doe   Doctor
   3 │     3  Joe Blogs  missing
   4 │     4  missing    Farmer

julia> outerjoin(name, job2, on = [:ID => :identifier], renamecols = uppercase => lowercase)
4×3 DataFrame
 Row │ ID     NAME       job
     │ Int64  String?    String?
─────┼───────────────────────────
   1 │     1  John Doe   Lawyer
   2 │     2  Jane Doe   Doctor
   3 │     3  Joe Blogs  missing
   4 │     4  missing    Farmer

# DataAPI.rightjoinFunction

rightjoin(df1, df2; on, makeunique=false, source=nothing,
          validate=(false, false), renamecols=(identity => identity),
          matchmissing=:error, order=:undefined)

Выполняет правое соединение двух объектов фрейма данных и возвращает DataFrame, содержащий результат. Правое соединение включает все строки из df2.

Порядок строк в результате не определен и может измениться в будущих выпусках.

В возвращаемом фрейме данных тип столбцов, по которым соединяются фреймы данных, определяется типом этих столбцов в df2. Такое поведение может измениться в будущих выпусках.

Аргументы

  • df1, df2: соединяемые AbstractDataFrames

Именованные аргументы

  • on: имена ключевых столбцов, по которым следует соединить фреймы данных. Это может быть одно имя или вектор имен (для соединения по нескольким столбцам). Вместо имени можно использовать пару имен left=>right в случае, когда ключ имеет разные имена в df1 и df2 (разрешается смешивать имена и пары имен в векторе). Значения ключей сравниваются с помощью isequal. on является обязательным аргументом.

  • makeunique: если задано значение false (по умолчанию), возникает ошибка при обнаружении повторяющихся имен в столбцах, по которым не выполнено соединение; если задано значение true, к повторяющимся именам добавляется суффикс _i, (i, начиная с 1 для первого повторяющегося имени).

  • source: значение по умолчанию — nothing. Если Symbol или строка, добавляет столбец указателя с заданным именем, чтобы определить, появилась ли строка только в df2 ("right_only") или в обоих ("both"). Если имя уже используется, имя столбца будет изменено, если makeunique=true.

  • validate: следует ли проверять, что столбцы, переданные в качестве аргумента on, определяют уникальные ключи в каждом входном фрейме данных (в соответствии с isequal). Может быть кортежем или парой, первый элемент которой указывает, запускать ли проверку для df1, а второй — для df2. По умолчанию проверка не выполняется.

  • renamecols: пара (Pair), указывающая, как должны быть переименованы столбцы левого и правого фреймов данных в результирующем фрейме данных. Каждый элемент пары может представлять собой строку, или может быть передан символ (Symbol), в этом случае он добавляется к исходному имени столбца. В качестве альтернативы можно передать функцию, в этом случае она применяется к каждому имени столбца, которое передается ей в виде строки (String). Обратите внимание, что renamecols не влияет на столбцы on, имена которых всегда берутся из левого фрейма данных и остаются неизменными.

  • matchmissing: если имеет значение :error, возникает ошибка, если missing присутствует в столбцах on; если имеет значение :equal, missing разрешено и отсутствующие значения сопоставляются; если имеет значение :notequal, отсутствующие значения удаляются в столбцах on df1.

  • order: если :undefined (по умолчанию), порядок строк в результате не определен и может измениться в будущих выпусках. Если :left, сохраняется порядок строк из левого фрейма данных (несовпадающие строки помещаются в конец). Если :right, сохраняется порядок строк из правого фрейма данных.

Все столбцы возвращаемого фрейма данных будут поддерживать отсутствующие значения.

Не допускается соединение по столбцам, содержащим NaN или -0.0 в вещественной или мнимой частях числа. Чтобы выполнить соединение по таким значениям, используйте CategoricalArrays.jl и преобразуйте столбец, содержащий такие значения, в CategoricalVector.

При объединении категориальных столбцов on, отличающихся упорядочением уровней, упорядочение левого фрейма данных имеет приоритет над упорядочением правого фрейма данных.

Метаданные: метаданные на уровне таблиц и метаданные на уровне столбцов в стиле :note принимаются из df2 (включая столбцы ключей), за исключением столбцов, добавленных в него из df1, метаданные на уровне столбцов в стиле :note которого принимаются из df1.

См. также описание innerjoin, leftjoin, outerjoin, semijoin, antijoin, crossjoin.

Примеры

julia> name = DataFrame(ID=[1, 2, 3], Name=["John Doe", "Jane Doe", "Joe Blogs"])
3×2 DataFrame
 Row │ ID     Name
     │ Int64  String
─────┼──────────────────
   1 │     1  John Doe
   2 │     2  Jane Doe
   3 │     3  Joe Blogs

julia> job = DataFrame(ID=[1, 2, 4], Job=["Lawyer", "Doctor", "Farmer"])
3×2 DataFrame
 Row │ ID     Job
     │ Int64  String
─────┼───────────────
   1 │     1  Lawyer
   2 │     2  Doctor
   3 │     4  Farmer

julia> rightjoin(name, job, on = :ID)
3×3 DataFrame
 Row │ ID     Name      Job
     │ Int64  String?   String
─────┼─────────────────────────
   1 │     1  John Doe  Lawyer
   2 │     2  Jane Doe  Doctor
   3 │     4  missing   Farmer

julia> job2 = DataFrame(identifier=[1, 2, 4], Job=["Lawyer", "Doctor", "Farmer"])
3×2 DataFrame
 Row │ identifier  Job
     │ Int64       String
─────┼────────────────────
   1 │          1  Lawyer
   2 │          2  Doctor
   3 │          4  Farmer

julia> rightjoin(name, job2, on = :ID => :identifier, renamecols = "_left" => "_right")
3×3 DataFrame
 Row │ ID     Name_left  Job_right
     │ Int64  String?    String
─────┼─────────────────────────────
   1 │     1  John Doe   Lawyer
   2 │     2  Jane Doe   Doctor
   3 │     4  missing    Farmer

julia> rightjoin(name, job2, on = [:ID => :identifier], renamecols = uppercase => lowercase)
3×3 DataFrame
 Row │ ID     NAME      job
     │ Int64  String?   String
─────┼─────────────────────────
   1 │     1  John Doe  Lawyer
   2 │     2  Jane Doe  Doctor
   3 │     4  missing   Farmer

# DataAPI.semijoinFunction

semijoin(df1, df2; on, makeunique=false, validate=(false, false), matchmissing=:error)

Выполняет полусоединение двух объектов фрейма данных и возвращает DataFrame, содержащий результат. Полусоединение возвращает подмножество строк df1, которые совпадают с ключами в df2.

Порядок строк в результате сохраняется из df1.

Аргументы

  • df1, df2: соединяемые AbstractDataFrames

Именованные аргументы

  • on: имена ключевых столбцов, по которым следует соединить фреймы данных. Это может быть одно имя или вектор имен (для соединения по нескольким столбцам). Вместо имени можно использовать пару имен left=>right в случае, когда ключ имеет разные имена в df1 и df2 (разрешается смешивать имена и пары имен в векторе). Значения ключей сравниваются с помощью isequal. on является обязательным аргументом.

  • makeunique: игнорируется, так как столбцы не добавляются к столбцам df1 (он предоставляется для согласованности с другими функциями).

  • indicator: значение по умолчанию — nothing. Если Symbol или строка, добавляет категориальный столбец указателя с заданным именем, чтобы определить, появилась ли строка только в df1 ("left_only"), только в df2 ("right_only") или в обоих ("both"). Если имя уже используется, имя столбца будет изменено, если makeunique=true.

  • validate: следует ли проверять, что столбцы, переданные в качестве аргумента on, определяют уникальные ключи в каждом входном фрейме данных (в соответствии с isequal). Может быть кортежем или парой, первый элемент которой указывает, запускать ли проверку для df1, а второй — для df2. По умолчанию проверка не выполняется.

  • matchmissing: если имеет значение :error, возникает ошибка, если missing присутствует в столбцах on; если имеет значение :equal, missing разрешено и отсутствующие значения сопоставляются; если имеет значение :notequal, отсутствующие значения удаляются в столбцах on df2.

Не допускается соединение по столбцам, содержащим NaN или -0.0 в вещественной или мнимой частях числа. Чтобы выполнить соединение по таким значениям, используйте CategoricalArrays.jl и преобразуйте столбец, содержащий такие значения, в CategoricalVector.

При объединении категориальных столбцов on, отличающихся упорядочением уровней, упорядочение левого фрейма данных имеет приоритет над упорядочением правого фрейма данных.

Метаданные: метаданные на уровне таблиц и метаданные на уровне столбцов в стиле :note принимаются из df1.

См. также описание innerjoin, leftjoin, rightjoin, outerjoin, antijoin, crossjoin.

Примеры

julia> name = DataFrame(ID=[1, 2, 3], Name=["John Doe", "Jane Doe", "Joe Blogs"])
3×2 DataFrame
 Row │ ID     Name
     │ Int64  String
─────┼──────────────────
   1 │     1  John Doe
   2 │     2  Jane Doe
   3 │     3  Joe Blogs

julia> job = DataFrame(ID=[1, 2, 4], Job=["Lawyer", "Doctor", "Farmer"])
3×2 DataFrame
 Row │ ID     Job
     │ Int64  String
─────┼───────────────
   1 │     1  Lawyer
   2 │     2  Doctor
   3 │     4  Farmer

julia> semijoin(name, job, on = :ID)
2×2 DataFrame
 Row │ ID     Name
     │ Int64  String
─────┼─────────────────
   1 │     1  John Doe
   2 │     2  Jane Doe

julia> job2 = DataFrame(identifier=[1, 2, 4], Job=["Lawyer", "Doctor", "Farmer"])
3×2 DataFrame
 Row │ identifier  Job
     │ Int64       String
─────┼────────────────────
   1 │          1  Lawyer
   2 │          2  Doctor
   3 │          4  Farmer

julia> semijoin(name, job2, on = :ID => :identifier)
2×2 DataFrame
 Row │ ID     Name
     │ Int64  String
─────┼─────────────────
   1 │     1  John Doe
   2 │     2  Jane Doe

julia> semijoin(name, job2, on = [:ID => :identifier])
2×2 DataFrame
 Row │ ID     Name
     │ Int64  String
─────┼─────────────────
   1 │     1  John Doe
   2 │     2  Jane Doe

Группирование

# Base.getFunction

get(gd::GroupedDataFrame, key, default)

Get a group based on the values of the grouping columns.

key may be a GroupKey, NamedTuple or Tuple of grouping column values (in the same order as the cols argument to groupby). It may also be an AbstractDict, in which case the order of the arguments does not matter.

Examples

julia> df = DataFrame(a=repeat([:foo, :bar, :baz], outer=[2]),
                      b=repeat([2, 1], outer=[3]),
                      c=1:6);

julia> gd = groupby(df, :a)
GroupedDataFrame with 3 groups based on key: a
First Group (2 rows): a = :foo
 Row │ a       b      c
     │ Symbol  Int64  Int64
─────┼──────────────────────
   1 │ foo         2      1
   2 │ foo         1      4
⋮
Last Group (2 rows): a = :baz
 Row │ a       b      c
     │ Symbol  Int64  Int64
─────┼──────────────────────
   1 │ baz         2      3
   2 │ baz         1      6

julia> get(gd, (a=:bar,), nothing)
2×3 SubDataFrame
 Row │ a       b      c
     │ Symbol  Int64  Int64
─────┼──────────────────────
   1 │ bar         1      2
   2 │ bar         2      5

julia> get(gd, (:baz,), nothing)
2×3 SubDataFrame
 Row │ a       b      c
     │ Symbol  Int64  Int64
─────┼──────────────────────
   1 │ baz         2      3
   2 │ baz         1      6

julia> get(gd, (:qux,), nothing)

# DataFrames.groupbyFunction

groupby(d::AbstractDataFrame, cols;
        sort::Union{Bool, Nothing, NamedTuple}=nothing,
        skipmissing::Bool=false)

Возвращает GroupedDataFrame, представляющий представление AbstractDataFrame, разделенного на группы строк.

Аргументы

  • df: разделяемый AbstractDataFrame

  • cols: столбцы фрейма данных, по которым будет выполняться группировка. Это может быть любой селектор столбцов (символ (Symbol), строка или целое число; :, Cols, All, Between, Not, регулярное выражение или вектор символов (Symbol), строк или целых чисел). В частности, если селектор не выбирает столбцы, создается GroupedDataFrame из одной группы. Особый случай: если cols является одни столбцом или вектором столбцов, он может содержать столбцы, заключенные в функцию order, которая будет использоваться для определения порядка групп, если sort имеет значение true или NamedTuple (если sort имеет значение false, при передаче order возникнет ошибка; если sort имеет значение nothing, он задается как true при передаче order).

  • sort: если sort=true, сортирует группы согласно значениям группирующих столбцов cols; если sort=false, группы создаются в порядке их появления в df; если sort=nothing (по умолчанию), выбирается самый быстрый доступный алгоритм группировки, и в связи с этим порядок групп в результате не определен и может измениться в будущих выпусках. Ниже приведено описание текущей реализации. Кроме того, sort может быть NamedTuple и иметь некоторые или все поля alg, lt, by, rev и order . В этом случае группы сортируются, и их порядок соответствует порядку sortperm.

  • skipmissing: пропускать ли группы с отсутствующими (missing) значениями в одном из группирующих столбцов cols.

Подробные сведения

Итератор по GroupedDataFrame возвращает представление SubDataFrame для каждого группирования в df. В каждой группе сохраняется порядок строк в df.

GroupedDataFrame также поддерживает индексирование по группам, select, transform и combine (которое применяет функцию к каждой группе и объединяет результат во фрейм данных).

GroupedDataFrame также поддерживает интерфейс словаря. Ключи представляют собой объекты GroupKey, возвращаемые функцией keys(::GroupedDataFrame), которая также может быть использована для получения значений группирующих столбцов для каждой группы. Tuples и NamedTuple, содержащие значения группирующих столбцов (в том же порядке, что и аргумент cols), также принимаются в качестве индексов. И, наконец, AbstractDict можно использовать для индексации в сгруппированный фрейм данных, где ключи являются именами столбцов фрейма данных. В этом случае порядок ключей не имеет значения.

В текущей реализации, если группы sort=nothing упорядочиваются в порядке появления значений в группирующих столбцах, за исключением случаев, когда все группирующие столбцы предоставляют не nothing DataAPI.refpool, то порядок групп следует порядку значений, возвращаемых DataAPI.refpool. Частное применение этого правила: если все cols являются CategoricalVector, группы всегда сортируются. Целочисленные столбцы с узким диапазоном также используют эту оптимизацию, поэтому порядок групп при группировке по целочисленным столбцам не определен. Столбец считается целочисленным при выборе алгоритма группировки, если его eltype является подтипом Union{Missing, Real}, все его элементы либо отсутствуют (missing), либо проходят тест isinteger, ни один из них не равен -0.0.

См. также описание

Примеры

julia> df = DataFrame(a=repeat([1, 2, 3, 4], outer=[2]),
                      b=repeat([2, 1], outer=[4]),
                      c=1:8);

julia> gd = groupby(df, :a)
GroupedDataFrame with 4 groups based on key: a
First Group (2 rows): a = 1
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      2      1
   2 │     1      2      5
⋮
Last Group (2 rows): a = 4
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     4      1      4
   2 │     4      1      8

julia> gd[1]
2×3 SubDataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      2      1
   2 │     1      2      5

julia> last(gd)
2×3 SubDataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     4      1      4
   2 │     4      1      8

julia> gd[(a=3,)]
2×3 SubDataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     3      2      3
   2 │     3      2      7

julia> gd[Dict("a" => 3)]
2×3 SubDataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     3      2      3
   2 │     3      2      7

julia> gd[(3,)]
2×3 SubDataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     3      2      3
   2 │     3      2      7

julia> k = first(keys(gd))
GroupKey: (a = 1,)

julia> gd[k]
2×3 SubDataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      2      1
   2 │     1      2      5

julia> for g in gd
           println(g)
       end
2×3 SubDataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     1      2      1
   2 │     1      2      5
2×3 SubDataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     2      1      2
   2 │     2      1      6
2×3 SubDataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     3      2      3
   2 │     3      2      7
2×3 SubDataFrame
 Row │ a      b      c
     │ Int64  Int64  Int64
─────┼─────────────────────
   1 │     4      1      4
   2 │     4      1      8

# DataFrames.groupcolsFunction

groupcols(gd::GroupedDataFrame)

Возвращает вектор Symbol имен столбцов в parent(gd), используемой для группировки.

# DataFrames.groupindicesFunction

groupindices(gd::GroupedDataFrame)

Возвращает вектор индексов групп для каждой строки parent(gd).

Строкам, появляющимся в группе gd[i], присваивается индекс i. Строкам, отсутствующим в любых группах, присваивается missing (это может произойти, если skipmissing=true было передано при создании gd, или если gd является подмножеством из более крупного GroupedDataFrame).

Синтаксис groupindices => target_col_name (или просто groupindices без без указания имени целевого столбца) также поддерживается в мини-языке преобразования при передаче GroupedDataFrame функциям преобразования (combine, select и т. д.).

Примеры

julia> df = DataFrame(id=["a", "c", "b", "b", "a"])
5×1 DataFrame
 Row │ id
     │ String
─────┼────────
   1 │ a
   2 │ c
   3 │ b
   4 │ b
   5 │ a

julia> gdf = groupby(df, :id);

julia> combine(gdf, groupindices)
3×2 DataFrame
 Row │ id      groupindices
     │ String  Int64
─────┼──────────────────────
   1 │ a                  1
   2 │ c                  2
   3 │ b                  3

julia> select(gdf, groupindices => :gid)
5×2 DataFrame
 Row │ id      gid
     │ String  Int64
─────┼───────────────
   1 │ a           1
   2 │ c           2
   3 │ b           3
   4 │ b           3
   5 │ a           1

# Base.keysFunction

keys(gd::GroupedDataFrame)

Get the set of keys for each group of the GroupedDataFrame gd as a GroupKeys object. Each key is a GroupKey, which behaves like a NamedTuple holding the values of the grouping columns for a given group. Unlike the equivalent Tuple, NamedTuple, and AbstractDict, these keys can be used to index into gd efficiently. The ordering of the keys is identical to the ordering of the groups of gd under iteration and integer indexing.

Examples

julia> df = DataFrame(a=repeat([:foo, :bar, :baz], outer=[4]),
                      b=repeat([2, 1], outer=[6]),
                      c=1:12);

julia> gd = groupby(df, [:a, :b])
GroupedDataFrame with 6 groups based on keys: a, b
First Group (2 rows): a = :foo, b = 2
 Row │ a       b      c
     │ Symbol  Int64  Int64
─────┼──────────────────────
   1 │ foo         2      1
   2 │ foo         2      7
⋮
Last Group (2 rows): a = :baz, b = 1
 Row │ a       b      c
     │ Symbol  Int64  Int64
─────┼──────────────────────
   1 │ baz         1      6
   2 │ baz         1     12

julia> keys(gd)
6-element DataFrames.GroupKeys{GroupedDataFrame{DataFrame}}:
 GroupKey: (a = :foo, b = 2)
 GroupKey: (a = :bar, b = 1)
 GroupKey: (a = :baz, b = 2)
 GroupKey: (a = :foo, b = 1)
 GroupKey: (a = :bar, b = 2)
 GroupKey: (a = :baz, b = 1)

julia> k = keys(gd)[1]
GroupKey: (a = :foo, b = 2)

julia> keys(k)
2-element Vector{Symbol}:
 :a
 :b

julia> values(k)  # Same as Tuple(k)
(:foo, 2)

julia> NamedTuple(k)
(a = :foo, b = 2)

julia> k.a
:foo

julia> k[:a]
:foo

julia> k[1]
:foo

Keys can be used as indices to retrieve the corresponding group from their GroupedDataFrame:

julia> gd[k]
2×3 SubDataFrame
 Row │ a       b      c
     │ Symbol  Int64  Int64
─────┼──────────────────────
   1 │ foo         2      1
   2 │ foo         2      7

julia> gd[keys(gd)[1]] == gd[1]
true
keys(dfc::DataFrameColumns)

Get a vector of column names of dfc as Symbols.

# Base.parentFunction

parent(gd::GroupedDataFrame)

Return the parent data frame of gd.

# DataFrames.proprowFunction

proprow

Вычисляет долю строк, принадлежащих каждой группе, т. е. количество строк, деленное на общее количество строк в GroupedDataFrame.

Эту функцию можно использовать только в мини-языке преобразования через синтаксис proprow => target_col_name (или просто proprow без указания имени целевого столбца) при передаче GroupedDataFrame функциям преобразования (combine, select и т. д.).

Примеры

julia> df = DataFrame(id=["a", "c", "b", "b", "a", "b"])
6×1 DataFrame
 Row │ id
     │ String
─────┼────────
   1 │ a
   2 │ c
   3 │ b
   4 │ b
   5 │ a
   6 │ b

julia> gdf = groupby(df, :id);

julia> combine(gdf, proprow)
3×2 DataFrame
 Row │ id      proprow
     │ String  Float64
─────┼──────────────────
   1 │ a       0.333333
   2 │ c       0.166667
   3 │ b       0.5

julia> select(gdf, proprow => :frac)
6×2 DataFrame
 Row │ id      frac
     │ String  Float64
─────┼──────────────────
   1 │ a       0.333333
   2 │ c       0.166667
   3 │ b       0.5
   4 │ b       0.5
   5 │ a       0.333333
   6 │ b       0.5

# DataFrames.valuecolsFunction

valuecols(gd::GroupedDataFrame)

Возвращает вектор Symbol имен столбцов в parent(gd), не используемой для группировки.

Фильтрация строк

# Base.alluniqueFunction

allunique(df::AbstractDataFrame, cols=:)

Возвращает true, если ни одна из строк df не дублируется. Две строки являются дубликатами, если все их столбцы содержат одинаковые значения (согласно isequal) для всех столбцов в cols (по умолчанию все столбцы).

Аргументы

  • df: AbstractDataFrame

  • cols: селектор, указывающий сравниваемые столбцы или их преобразования. Это может быть любой селектор столбцов или преобразование, принимаемое select.

См. также описание unique и nonunique.

Примеры

julia> df = DataFrame(i=1:4, x=[1, 2, 1, 2])
4×2 DataFrame
 Row │ i      x
     │ Int64  Int64
─────┼──────────────
   1 │     1      1
   2 │     2      2
   3 │     3      1
   4 │     4      2

julia> allunique(df)
true

julia> allunique(df, :x)
false

julia> allunique(df, :i => ByRow(isodd))
false

# Base.deleteat!Function

deleteat!(df::DataFrame, inds)

Удаляет компоненты, указанные с помощью inds, из DataFrame df на месте и возвращает его.

Внутренним образом deleteat! вызывается для всех столбцов, поэтому inds должен быть вектором отсортированных и уникальных целых чисел, логическим вектором, целым числом или Not, заключающим в оболочку любой допустимый селектор.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Примеры

julia> df = DataFrame(a=1:3, b=4:6)
3×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      4
   2 │     2      5
   3 │     3      6

julia> deleteat!(df, 2)
2×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      4
   2 │     3      6

# Base.emptyFunction

empty(df::AbstractDataFrame)

Создает новый DataFrame с теми же именами столбцов и типами элементов столбцов, что и df, но без строк.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

# Base.empty!Function

empty!(df::DataFrame)

Удаляет все строки из df, делая каждый из его столбцов пустым.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Примеры

julia> df = DataFrame(a=1:3, b=4:6)
3×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      4
   2 │     2      5
   3 │     3      6

julia> empty!(df)
0×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┴──────────────

julia> df.a, df.b
(Int64[], Int64[])

# Base.filterFunction

filter(fun, df::AbstractDataFrame; view::Bool=false)
filter(cols => fun, df::AbstractDataFrame; view::Bool=false)

Возвращает фрейм данных, содержащий только строки из df, для которого fun возвращает true.

Если cols не указан, предикату fun передаются DataFrameRow. К элементам DataFrameRow можно получать доступ с помощью точечного синтаксиса или индексирования столбцов внутри fun.

Если cols не указан, предикату fun передаются элементы соответствующих столбцов в виде отдельных позиционных аргументов, если только cols не является селектором AsTable. В этом случае передается NamedTuple этих аргументов. cols может представлять собой любой селектор столбцов (символ (Symbol), строку или целое число; :, Cols, All, Between, Not, регулярное выражение или вектор символов (Symbol), строк или целых чисел), и дубликаты столбцов разрешены, если передается вектор символов (Symbol), строк или целых чисел.

Если view=false, возвращается только что выделенный DataFrame. Если view=true, то возвращается представление SubDataFrame для df.

Передача cols приводит к более эффективному выполнению операции для больших фреймов данных.

Этот метод определен, чтобы пакет DataFrames.jl реализовал API Julia для коллекций, но обычно рекомендуется использовать вместо него функцию subset , поскольку она согласована с другими функциями DataFrames.jl (в отличие от filter).

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

См. также описание filter!.

Примеры

julia> df = DataFrame(x=[3, 1, 2, 1], y=["b", "c", "a", "b"])
4×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     3  b
   2 │     1  c
   3 │     2  a
   4 │     1  b

julia> filter(row -> row.x > 1, df)
2×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     3  b
   2 │     2  a

julia> filter(row -> row["x"] > 1, df)
2×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     3  b
   2 │     2  a

julia> filter(:x => x -> x > 1, df)
2×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     3  b
   2 │     2  a

julia> filter([:x, :y] => (x, y) -> x == 1 || y == "b", df)
3×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     3  b
   2 │     1  c
   3 │     1  b

julia> filter(AsTable(:) => nt -> nt.x == 1 || nt.y == "b", df)
3×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     3  b
   2 │     1  c
   3 │     1  b
filter(fun, gdf::GroupedDataFrame; ungroup::Bool=false)
filter(cols => fun, gdf::GroupedDataFrame; ungroup::Bool=false)

Возвращает только группы в gd, для которых fun возвращает true в виде GroupedDataFrame, если ungroup=false (по умолчанию), или в виде фрейма данных, если ungroup=true.

Если cols не указан, предикат fun вызывается с SubDataFrame для каждой группы.

Если cols не указан, предикат fun вызывается для каждой группы с представлениями соответствующих столбцов в виде отдельных позиционных аргументов, если только cols не является селектором AsTable. В этом случае передается NamedTuple этих аргументов. cols может представлять собой любой селектор столбцов (символ (Symbol), строку или целое число; :, Cols, All, Between, Not, регулярное выражение или вектор символов (Symbol), строк или целых чисел), дубликаты столбцов разрешены, если передается вектор символов (Symbol), строк или целых чисел.

Этот метод определен, чтобы пакет DataFrames.jl реализовал API Julia для коллекций, но обычно рекомендуется использовать вместо него функцию subset , поскольку она согласована с другими функциями DataFrames.jl (в отличие от filter).

Примеры

julia> df = DataFrame(g=[1, 2], x=['a', 'b']);

julia> gd = groupby(df, :g)
GroupedDataFrame with 2 groups based on key: g
First Group (1 row): g = 1
 Row │ g      x
     │ Int64  Char
─────┼─────────────
   1 │     1  a
⋮
Last Group (1 row): g = 2
 Row │ g      x
     │ Int64  Char
─────┼─────────────
   1 │     2  b

julia> filter(x -> x.x[1] == 'a', gd)
GroupedDataFrame with 1 group based on key: g
First Group (1 row): g = 1
 Row │ g      x
     │ Int64  Char
─────┼─────────────
   1 │     1  a

julia> filter(:x => x -> x[1] == 'a', gd)
GroupedDataFrame with 1 group based on key: g
First Group (1 row): g = 1
 Row │ g      x
     │ Int64  Char
─────┼─────────────
   1 │     1  a

julia> filter(:x => x -> x[1] == 'a', gd, ungroup=true)
1×2 DataFrame
 Row │ g      x
     │ Int64  Char
─────┼─────────────
   1 │     1  a

# Base.filter!Function

filter!(fun, df::AbstractDataFrame)
filter!(cols => fun, df::AbstractDataFrame)

Удаляет строки из фрейма данных df, для которого fun возвращает false.

Если cols не указан, предикату fun передаются DataFrameRow. К элементам DataFrameRow можно получать доступ с помощью точечного синтаксиса или индексирования столбцов внутри fun.

Если cols не указан, предикату fun передаются элементы соответствующих столбцов в виде отдельных позиционных аргументов, если только cols не является селектором AsTable. В этом случае передается NamedTuple этих аргументов. cols может представлять собой любой селектор столбцов (символ (Symbol), строку или целое число; :, Cols, All, Between, Not, регулярное выражение или вектор символов (Symbol), строк или целых чисел), и дубликаты столбцов разрешены, если передается вектор символов (Symbol), строк или целых чисел.

Передача cols приводит к более эффективному выполнению операции для больших фреймов данных.

Этот метод определен, чтобы пакет DataFrames.jl реализовал API Julia для коллекций, но обычно рекомендуется использовать вместо него функцию subset! , поскольку она согласована с другими функциями DataFrames.jl (в отличие от filter!).

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

См. также описание filter.

Примеры

julia> df = DataFrame(x=[3, 1, 2, 1], y=["b", "c", "a", "b"])
4×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     3  b
   2 │     1  c
   3 │     2  a
   4 │     1  b

julia> filter!(row -> row.x > 1, df)
2×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     3  b
   2 │     2  a

julia> filter!(row -> row["x"] > 1, df)
2×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     3  b
   2 │     2  a

julia> filter!(:x => x -> x == 3, df)
1×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     3  b

julia> df = DataFrame(x=[3, 1, 2, 1], y=["b", "c", "a", "b"]);

julia> filter!([:x, :y] => (x, y) -> x == 1 || y == "b", df)
3×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     3  b
   2 │     1  c
   3 │     1  b

julia> df = DataFrame(x=[3, 1, 2, 1], y=["b", "c", "a", "b"]);

julia> filter!(AsTable(:) => nt -> nt.x == 1 || nt.y == "b", df)
3×2 DataFrame
 Row │ x      y
     │ Int64  String
─────┼───────────────
   1 │     3  b
   2 │     1  c
   3 │     1  b

# Base.keepat!Function

keepat!(df::DataFrame, inds)

Удаляет строки по всем индексам, не указанным с помощью inds, из DataFrame df на месте и возвращает его.

Внутренним образом deleteat! вызывается для всех столбцов, поэтому inds должен быть вектором отсортированных и уникальных целых чисел, логическим вектором, целым числом или Not, заключающим в оболочку любой допустимый селектор.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Примеры

julia> df = DataFrame(a=1:3, b=4:6)
3×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      4
   2 │     2      5
   3 │     3      6

julia> keepat!(df, [1, 3])
2×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      4
   2 │     3      6

# Base.firstFunction

first(df::AbstractDataFrame)

Получает первую строку df в виде DataFrameRow.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

first(df::AbstractDataFrame, n::Integer; view::Bool=false)

Получает фрейм данных с n последних строк df.

Если view=false, возвращается только что выделенный DataFrame. Если view=true, возвращается представление SubDataFrame для df.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

# Base.lastFunction

last(df::AbstractDataFrame)

Получает последнюю строку df в виде DataFrameRow.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

last(df::AbstractDataFrame, n::Integer; view::Bool=false)

Получает фрейм данных с n последних строк df.

Если view=false, возвращается только что выделенный DataFrame. Если view=true, возвращается представление SubDataFrame для df.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

# DataFrames.nonuniqueFunction

nonunique(df::AbstractDataFrame; keep::Symbol=:first)
nonunique(df::AbstractDataFrame, cols; keep::Symbol=:first)

Возвращает Vector{Bool}, в котором записи true означают повторяющиеся строки.

Повторяющиеся строки — это строки, для которых по крайней мере еще одна строка содержит одинаковые значения (согласно isequal) для всех столбцов в cols (по умолчанию все столбцы). Если keep=:first (по умолчанию), только первое вхождение набора повторяющихся строк обозначается записью false. Если keep=:last (по умолчанию), только последнее вхождение набора повторяющихся строк обозначается записью false. Если keep=:noduplicates, только строки без дубликатов обозначаются записью false.

Аргументы

  • df: AbstractDataFrame.

  • cols: селектор, указывающий сравниваемые столбцы или их преобразования. Это может быть любой селектор столбцов или преобразование, принимаемое

функцией select, которая возвращает хотя бы один столбец, если df имеет как минимум один столбец.

См. также описание unique и unique!.

Примеры

julia> df = DataFrame(i=1:4, x=[1, 2, 1, 2])
4×2 DataFrame
 Row │ i      x
     │ Int64  Int64
─────┼──────────────
   1 │     1      1
   2 │     2      2
   3 │     3      1
   4 │     4      2

julia> df = vcat(df, df)
8×2 DataFrame
 Row │ i      x
     │ Int64  Int64
─────┼──────────────
   1 │     1      1
   2 │     2      2
   3 │     3      1
   4 │     4      2
   5 │     1      1
   6 │     2      2
   7 │     3      1
   8 │     4      2

julia> nonunique(df)
8-element Vector{Bool}:
 0
 0
 0
 0
 1
 1
 1
 1

julia> nonunique(df, keep=:last)
8-element Vector{Bool}:
 1
 1
 1
 1
 0
 0
 0
 0

julia> nonunique(df, 2)
8-element Vector{Bool}:
 0
 0
 1
 1
 1
 1
 1
 1

# Base.Iterators.onlyFunction

only(df::AbstractDataFrame)

Если df содержит одну строку, возвращает его как DataFrameRow. В противном случае возникает ошибка ArgumentError.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

# Base.pop!Function

pop!(df::DataFrame)

Удаляет последнюю строку из df и возвращает кортеж (NamedTuple), созданный из этой строки.

Использование этого метода для очень широких массивов данных может привести к дорогостоящей компиляции.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Примеры

julia> df = DataFrame(a=1:3, b=4:6)
3×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      4
   2 │     2      5
   3 │     3      6

julia> pop!(df)
(a = 3, b = 6)

julia> df
2×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      4
   2 │     2      5

# Base.popat!Function

popat!(df::DataFrame, i::Integer)

Удаляет i-ю строку из df и возвращает кортеж (NamedTuple), созданный из этой строки.

Использование этого метода для очень широких массивов данных может привести к дорогостоящей компиляции.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Примеры

julia> df = DataFrame(a=1:3, b=4:6)
3×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      4
   2 │     2      5
   3 │     3      6

julia> popat!(df, 2)
(a = 2, b = 5)

julia> df
2×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      4
   2 │     3      6

# Base.popfirst!Function

popfirst!(df::DataFrame)

Удаляет первую строку из df и возвращает NamedTuple, созданный из этой строки.

Использование этого метода для очень широких массивов данных может привести к дорогостоящей компиляции.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Примеры

julia> df = DataFrame(a=1:3, b=4:6)
3×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      4
   2 │     2      5
   3 │     3      6

julia> popfirst!(df)
(a = 1, b = 4)

julia> df
2×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     2      5
   2 │     3      6

# Base.resize!Function

resize!(df::DataFrame, n::Integer)

Изменяет размер df, чтобы получить n строк путем вызова функции resize! для всех столбцов df.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Примеры

julia> df = DataFrame(a=1:3, b=4:6)
3×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      4
   2 │     2      5
   3 │     3      6

julia> resize!(df, 2)
2×2 DataFrame
 Row │ a      b
     │ Int64  Int64
─────┼──────────────
   1 │     1      4
   2 │     2      5

# DataFrames.subsetFunction

subset(df::AbstractDataFrame, args...;
       skipmissing::Bool=false, view::Bool=false, threads::Bool=true)
subset(gdf::GroupedDataFrame, args...;
       skipmissing::Bool=false, view::Bool=false,
       ungroup::Bool=true, threads::Bool=true)

Возвращает копию фрейма данных df или родителя gdf, содержащую только строки, для которых все значения, полученные преобразованиями args, для заданной строки имеют значение true. Все преобразования должны создавать векторы, содержащие true или false. Когда первый аргумент является GroupedDataFrame, преобразования также могут возвращать одно значение true или false, что приводит к включению или исключению целой группы.

Если skipmissing=false (по умолчанию), args требуются для получения результатов, содержащих только логические (Bool) значения. Если skipmissing=true, допускается дополнительное значение missing, которое рассматривается как false (т. е. строки, для которых одно из условий возвращает missing, пропускаются).

Каждый аргумент, передаваемый в args, может быть любым спецификатором, соответствующим правилам, описанным для select, с ограничением, что:

  • указание имени целевого столбца недопустимо, поскольку subset не создает новых столбцов;

  • каждое переданное преобразование должно возвращать скаляр или вектор (возвращение AbstractDataFrame, NamedTuple, DataFrameRow или AbstractMatrix не поддерживается).

Если view=true, возвращается представление SubDataFrame вместо DataFrame.

Если ungroup=false, результирующий фрейм данных перегруппировывается на основе тех же столбцов группировки, что и gdf, и возвращается GroupedDataFrame (с сохранением порядка групп из gdf).

Если threads=true (по умолчанию), преобразования могут осуществляться в отдельных задачах, которые могут выполняться параллельно (возможно, с применением к нескольким строкам или группам одновременно). Тот момент, порождаются ли задачи, и их количество определяется автоматически. Установите значение false, если некоторые преобразования требуют последовательного выполнения или не являются потокобезопасными.

Если передается GroupedDataFrame, он должен включать все группы, присутствующие во фрейме данных parent, как в select!.

Обратите внимание, что функция subset работает точно так же, как и другие функции преобразования, определенные в DataFrames.jl. Это предпочтительный способ выделения подмножества строк фрейма данных или сгруппированного фрейма данных. В частности, она использует другой набор правил для указания преобразований, чем filter, который реализуется в DataFrames.jl для обеспечения поддержки стандартного API Julia для коллекций.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

См. также описание subset!, filter, select.

Примеры

julia> df = DataFrame(id=1:4, x=[true, false, true, false],
                      y=[true, true, false, false],
                      z=[true, true, missing, missing], v=[1, 2, 11, 12])
4×5 DataFrame
 Row │ id     x      y      z        v
     │ Int64  Bool   Bool   Bool?    Int64
─────┼─────────────────────────────────────
   1 │     1   true   true     true      1
   2 │     2  false   true     true      2
   3 │     3   true  false  missing     11
   4 │     4  false  false  missing     12

julia> subset(df, :x)
2×5 DataFrame
 Row │ id     x     y      z        v
     │ Int64  Bool  Bool   Bool?    Int64
─────┼────────────────────────────────────
   1 │     1  true   true     true      1
   2 │     3  true  false  missing     11

julia> subset(df, :v => x -> x .> 3)
2×5 DataFrame
 Row │ id     x      y      z        v
     │ Int64  Bool   Bool   Bool?    Int64
─────┼─────────────────────────────────────
   1 │     3   true  false  missing     11
   2 │     4  false  false  missing     12

julia> subset(df, :x, :y => ByRow(!))
1×5 DataFrame
 Row │ id     x     y      z        v
     │ Int64  Bool  Bool   Bool?    Int64
─────┼────────────────────────────────────
   1 │     3  true  false  missing     11

julia> subset(df, :x, :z, skipmissing=true)
1×5 DataFrame
 Row │ id     x     y     z      v
     │ Int64  Bool  Bool  Bool?  Int64
─────┼─────────────────────────────────
   1 │     1  true  true   true      1

julia> subset(df, :x, :z)
ERROR: ArgumentError: missing was returned in condition number 2 but only true or false are allowed; pass skipmissing=true to skip missing values

julia> subset(groupby(df, :y), :v => x -> x .> minimum(x))
2×5 DataFrame
 Row │ id     x      y      z        v
     │ Int64  Bool   Bool   Bool?    Int64
─────┼─────────────────────────────────────
   1 │     2  false   true     true      2
   2 │     4  false  false  missing     12

julia> subset(groupby(df, :y), :v => x -> minimum(x) > 5)
2×5 DataFrame
 Row │ id     x      y      z        v
     │ Int64  Bool   Bool   Bool?    Int64
─────┼─────────────────────────────────────
   1 │     3   true  false  missing     11
   2 │     4  false  false  missing     12

# DataFrames.subset!Function

subset!(df::AbstractDataFrame, args...;
        skipmissing::Bool=false, threads::Bool=true)
subset!(gdf::GroupedDataFrame{DataFrame}, args...;
        skipmissing::Bool=false, ungroup::Bool=true, threads::Bool=true)

Обновляет фрейм данных df или родитель gdf на месте так, чтобы он содержал только строки, для которых все значения, полученные преобразованиями args, для заданной строки имеют значение true. Все преобразования должны создавать векторы, содержащие true или false. Если первый аргумент является GroupedDataFrame, преобразования также могут возвращать одно значение true или false, что приводит к включению или исключению целой группы.

Если skipmissing=false (по умолчанию), args требуются для получения результатов, содержащих только логические (Bool) значения. Если skipmissing=true, допускается дополнительное значение missing, которое рассматривается как false (т. е. строки, для которых одно из условий возвращает missing, пропускаются).

Каждый аргумент, передаваемый в args, может быть любым спецификатором, соответствующим правилам, описанным для select, с ограничением, что:

  • указание имени целевого столбца недопустимо, поскольку subset! не создает новых столбцов;

  • каждое переданное преобразование должно возвращать скаляр или вектор (возвращение AbstractDataFrame, NamedTuple, DataFrameRow или AbstractMatrix не поддерживается).

Если ungroup=false, передаваемый GroupedDataFrame gdf, обновляется (с сохранением порядка его групп) и возвращается.

Если threads=true (по умолчанию), преобразования могут осуществляться в отдельных задачах, которые могут выполняться параллельно (возможно, с применением к нескольким строкам или группам одновременно). Тот момент, порождаются ли задачи, и их количество определяется автоматически. Установите значение false, если некоторые преобразования требуют последовательного выполнения или не являются потокобезопасными.

Если GroupedDataFrame является подмножеством, он должен включать все группы, присутствующие в родительском (parent) фрейме данных, как в select!. В этом случае передаваемый GroupedDataFrame обновляется так, чтобы иметь правильные группы, после того как его родитель будет обновлен.

Обратите внимание, что функция subset! работает точно так же, как и другие функции преобразования, определенные в DataFrames.jl. Это предпочтительный способ выделения подмножества строк фрейма данных или сгруппированного фрейма данных. В частности, она использует другой набор правил для указания преобразований, чем filter!, который реализуется в DataFrames.jl для обеспечения поддержки стандартного API Julia для коллекций.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

См. также описание subset, filter!, select!.

Примеры

julia> df = DataFrame(id=1:4, x=[true, false, true, false], y=[true, true, false, false])
4×3 DataFrame
 Row │ id     x      y
     │ Int64  Bool   Bool
─────┼─────────────────────
   1 │     1   true   true
   2 │     2  false   true
   3 │     3   true  false
   4 │     4  false  false

julia> subset!(df, :x, :y => ByRow(!));

julia> df
1×3 DataFrame
 Row │ id     x     y
     │ Int64  Bool  Bool
─────┼────────────────────
   1 │     3  true  false

julia> df = DataFrame(id=1:4, y=[true, true, false, false], v=[1, 2, 11, 12]);

julia> subset!(groupby(df, :y), :v => x -> x .> minimum(x));

julia> df
2×3 DataFrame
 Row │ id     y      v
     │ Int64  Bool   Int64
─────┼─────────────────────
   1 │     2   true      2
   2 │     4  false     12

julia> df = DataFrame(id=1:4, x=[true, false, true, false],
                      z=[true, true, missing, missing], v=1:4)
4×4 DataFrame
 Row │ id     x      z        v
     │ Int64  Bool   Bool?    Int64
─────┼──────────────────────────────
   1 │     1   true     true      1
   2 │     2  false     true      2
   3 │     3   true  missing      3
   4 │     4  false  missing      4

julia> subset!(df, :x, :z)
ERROR: ArgumentError: missing was returned in condition number 2 but only true or false are allowed; pass skipmissing=true to skip missing values

julia> subset!(df, :x, :z, skipmissing=true);

julia> df
1×4 DataFrame
 Row │ id     x     z      v
     │ Int64  Bool  Bool?  Int64
─────┼───────────────────────────
   1 │     1  true   true      1

julia> df = DataFrame(id=1:4, x=[true, false, true, false], y=[true, true, false, false],
                      z=[true, true, missing, missing], v=[1, 2, 11, 12]);

julia> subset!(groupby(df, :y), :v => x -> x .> minimum(x));

julia> df
2×5 DataFrame
 Row │ id     x      y      z        v
     │ Int64  Bool   Bool   Bool?    Int64
─────┼─────────────────────────────────────
   1 │     2  false   true     true      2
   2 │     4  false  false  missing     12

julia> df = DataFrame(id=1:4, x=[true, false, true, false], y=[true, true, false, false],
                      z=[true, true, missing, missing], v=[1, 2, 11, 12]);

julia> subset!(groupby(df, :y), :v => x -> minimum(x) > 5);

julia> df
2×5 DataFrame
 Row │ id     x      y      z        v
     │ Int64  Bool   Bool   Bool?    Int64
─────┼─────────────────────────────────────
   1 │     3   true  false  missing     11
   2 │     4  false  false  missing     12

# Base.uniqueFunction

unique(df::AbstractDataFrame; view::Bool=false, keep::Symbol=:first)
unique(df::AbstractDataFrame, cols; view::Bool=false, keep::Symbol=:first)

Возвращает фрейм данных, содержащий только уникальные строки в df.

Неуникальные (повторяющиеся) строки — это строки, для которых по крайней мере еще одна строка содержит одинаковые значения (согласно isequal) для всех столбцов в cols (по умолчанию все столбцы). Если keep=:first (по умолчанию), сохраняется только первое вхождение набора повторяющихся строк. Если keep=:last (по умолчанию), сохраняется только последнее вхождение набора повторяющихся строк. Если keep=:noduplicates, сохраняются только строки без дубликатов.

Если view=false, возвращается только что выделенный DataFrame, а если view=true, возвращается представление SubDataFrame для df.

Аргументы

  • df: AbstractDataFrame.

  • cols: селектор, указывающий сравниваемые столбцы или их преобразования. Это может быть любой селектор столбцов или преобразование, принимаемое

функцией select, которая возвращает хотя бы один столбец, если df имеет как минимум один столбец.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

См. также описание unique!, nonunique.

Примеры

julia> df = DataFrame(i=1:4, x=[1, 2, 1, 2])
4×2 DataFrame
 Row │ i      x
     │ Int64  Int64
─────┼──────────────
   1 │     1      1
   2 │     2      2
   3 │     3      1
   4 │     4      2

julia> df = vcat(df, df)
8×2 DataFrame
 Row │ i      x
     │ Int64  Int64
─────┼──────────────
   1 │     1      1
   2 │     2      2
   3 │     3      1
   4 │     4      2
   5 │     1      1
   6 │     2      2
   7 │     3      1
   8 │     4      2

julia> unique(df)   # не изменяет фрейм данных
4×2 DataFrame
 Row │ i      x
     │ Int64  Int64
─────┼──────────────
   1 │     1      1
   2 │     2      2
   3 │     3      1
   4 │     4      2

julia> unique(df, 2)
2×2 DataFrame
 Row │ i      x
     │ Int64  Int64
─────┼──────────────
   1 │     1      1
   2 │     2      2

julia> unique(df, keep=:noduplicates)
0×2 DataFrame
 Row │ i      x
     │ Int64  Int64
─────┴──────────────

# Base.unique!Function

unique!(df::AbstractDataFrame; keep::Symbol=:first)
unique!(df::AbstractDataFrame, cols; keep::Symbol=:first)

Обновляет фрейм данных (df) на месте так, чтобы он содержал только уникальные строки.

Неуникальные (повторяющиеся) строки — это строки, для которых по крайней мере еще одна строка содержит одинаковые значения (согласно isequal) для всех столбцов в cols (по умолчанию все столбцы). Если keep=:first (по умолчанию), сохраняется только первое вхождение набора повторяющихся строк. Если keep=:last (по умолчанию), сохраняется только последнее вхождение набора повторяющихся строк. Если keep=:noduplicates, сохраняются только строки без дубликатов.

Аргументы

  • df: AbstractDataFrame.

  • cols: индикатор столбца (Symbol, Int, Vector{Symbol}, Regex и т. д.), указывающий сравниваемые столбцы. Это может быть любой селектор столбцов или преобразование, принимаемое функцией select, которая возвращает хотя бы один столбец, если df имеет как минимум один столбец.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

См. также описание unique!, nonunique.

Примеры

julia> df = DataFrame(i=1:4, x=[1, 2, 1, 2])
4×2 DataFrame
 Row │ i      x
     │ Int64  Int64
─────┼──────────────
   1 │     1      1
   2 │     2      2
   3 │     3      1
   4 │     4      2

julia> df = vcat(df, df)
8×2 DataFrame
 Row │ i      x
     │ Int64  Int64
─────┼──────────────
   1 │     1      1
   2 │     2      2
   3 │     3      1
   4 │     4      2
   5 │     1      1
   6 │     2      2
   7 │     3      1
   8 │     4      2

julia> unique!(copy(df))  # изменяет фрейм данных
4×2 DataFrame
 Row │ i      x
     │ Int64  Int64
─────┼──────────────
   1 │     1      1
   2 │     2      2
   3 │     3      1
   4 │     4      2

julia> unique(df, keep=:noduplicates)
0×2 DataFrame
 Row │ i      x
     │ Int64  Int64
─────┴──────────────

Работа с отсутствующими значениями

# Missings.allowmissingFunction

allowmissing(df::AbstractDataFrame, cols=:)

Возвращает копию фрейма данных df со столбцами cols, преобразованными в тип элемента Union{T, Missing} из T, чтобы обеспечить поддержку отсутствующих значений.

cols может представлять собой любой селектор столбцов (символ (Symbol), строку или целое число; :, Cols, All, Between, Not, регулярное выражение или вектор символов (Symbol), строк или целых чисел).

Если cols отсутствует, преобразуются все столбцы во фрейме данных.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Примеры

julia> df = DataFrame(a=[1, 2])
2×1 DataFrame
 Row │ a
     │ Int64
─────┼───────
   1 │     1
   2 │     2

julia> allowmissing(df)
2×1 DataFrame
 Row │ a
     │ Int64?
─────┼────────
   1 │      1
   2 │      2

# DataFrames.allowmissing!Function

allowmissing!(df::DataFrame, cols=:)

Преобразует столбцы cols фрейма данных df из типа элемента T в Union{T, Missing} для поддержки отсутствующих значений.

cols может представлять собой любой селектор столбцов (символ (Symbol), строку или целое число; :, Cols, All, Between, Not, регулярное выражение или вектор символов (Symbol), строк или целых чисел).

Если cols отсутствует, преобразуются все столбцы во фрейме данных.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

# DataFrames.completecasesFunction

completecases(df::AbstractDataFrame, cols=:)

Возвращает логический вектор с записями true, указывающими строки без отсутствующих значений (завершенные случаи) во фрейме данных df.

Если указано значение cols, учитываются только отсутствующие значения в соответствующих столбцах. cols может представлять собой любой селектор столбцов (символ (Symbol), строку или целое число; :, Cols, All, Between, Not, регулярное выражение или вектор символов (Symbol), строк или целых чисел), который возвращает хотя бы один столбец, если df имеет как минимум один столбец.

См. также описание dropmissing и dropmissing!. Используйте findall(completecases(df)) для получения индексов строк.

Примеры

julia> df = DataFrame(i=1:5,
                      x=[missing, 4, missing, 2, 1],
                      y=[missing, missing, "c", "d", "e"])
5×3 DataFrame
 Row │ i      x        y
     │ Int64  Int64?   String?
─────┼─────────────────────────
   1 │     1  missing  missing
   2 │     2        4  missing
   3 │     3  missing  c
   4 │     4        2  d
   5 │     5        1  e

julia> completecases(df)
5-element BitVector:
 0
 0
 0
 1
 1

julia> completecases(df, :x)
5-element BitVector:
 0
 1
 0
 1
 1

julia> completecases(df, [:x, :y])
5-element BitVector:
 0
 0
 0
 1
 1

# Missings.disallowmissingFunction

disallowmissing(df::AbstractDataFrame, cols=:; error::Bool=true)

Возвращает копию фрейма данных df со столбцами cols, преобразованными из типа элемента Union{T, Missing} в T, чтобы отменить поддержку отсутствующих значений.

cols может представлять собой любой селектор столбцов (символ (Symbol), строку или целое число; :, Cols, All, Between, Not, регулярное выражение или вектор символов (Symbol), строк или целых чисел).

Если cols отсутствует, преобразуются все столбцы во фрейме данных.

Если error=false, ошибка не возникает, а столбцы, содержащие значение missing, пропускаются.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Примеры

julia> df = DataFrame(a=Union{Int, Missing}[1, 2])
2×1 DataFrame
 Row │ a
     │ Int64?
─────┼────────
   1 │      1
   2 │      2

julia> disallowmissing(df)
2×1 DataFrame
 Row │ a
     │ Int64
─────┼───────
   1 │     1
   2 │     2

julia> df = DataFrame(a=[1, missing])
2×1 DataFrame
 Row │ a
     │ Int64?
─────┼─────────
   1 │       1
   2 │ missing

julia> disallowmissing(df, error=false)
2×1 DataFrame
 Row │ a
     │ Int64?
─────┼─────────
   1 │       1
   2 │ missing

# DataFrames.disallowmissing!Function

disallowmissing!(df::DataFrame, cols=:; error::Bool=true)

Преобразует столбцы cols фрейма данных df из типа элемента Union{T, Missing} в T, чтобы отменить поддержку отсутствующих значений.

cols может представлять собой любой селектор столбцов (символ (Symbol), строку или целое число; :, Cols, All, Between, Not, регулярное выражение или вектор символов (Symbol), строк или целых чисел).

Если cols отсутствует, преобразуются все столбцы во фрейме данных.

Если error=false, ошибка не возникает, а столбцы, содержащие значение missing, пропускаются.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

# DataFrames.dropmissingFunction

dropmissing(df::AbstractDataFrame, cols=:; view::Bool=false, disallowmissing::Bool=!view)

Возвращает фрейм данных, исключающий строки с отсутствующими значениями в df.

Если указано значение cols, учитываются только отсутствующие значения в соответствующих столбцах. cols может представлять собой любой селектор столбцов (символ (Symbol), строку или целое число; :, Cols, All, Between, Not, регулярное выражение или вектор символов (Symbol), строк или целых чисел).

Если view=false, возвращается только что выделенный DataFrame. Если view=true, возвращается представление SubDataFrame для df. В данном случае disallowmissing должен иметь значение false.

Если disallowmissing имеет значение true (по умолчанию, когда view имеет значение false), столбцы, указанные в cols, будут преобразованы так, чтобы запрещать отсутствующие значения, с помощью disallowmissing!.

См. также описание completecases и dropmissing!.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

Примеры

julia> df = DataFrame(i=1:5,
                      x=[missing, 4, missing, 2, 1],
                      y=[missing, missing, "c", "d", "e"])
5×3 DataFrame
 Row │ i      x        y
     │ Int64  Int64?   String?
─────┼─────────────────────────
   1 │     1  missing  missing
   2 │     2        4  missing
   3 │     3  missing  c
   4 │     4        2  d
   5 │     5        1  e

julia> dropmissing(df)
2×3 DataFrame
 Row │ i      x      y
     │ Int64  Int64  String
─────┼──────────────────────
   1 │     4      2  d
   2 │     5      1  e

julia> dropmissing(df, disallowmissing=false)
2×3 DataFrame
 Row │ i      x       y
     │ Int64  Int64?  String?
─────┼────────────────────────
   1 │     4       2  d
   2 │     5       1  e

julia> dropmissing(df, :x)
3×3 DataFrame
 Row │ i      x      y
     │ Int64  Int64  String?
─────┼───────────────────────
   1 │     2      4  missing
   2 │     4      2  d
   3 │     5      1  e

julia> dropmissing(df, [:x, :y])
2×3 DataFrame
 Row │ i      x      y
     │ Int64  Int64  String
─────┼──────────────────────
   1 │     4      2  d
   2 │     5      1  e

# DataFrames.dropmissing!Function

dropmissing!(df::AbstractDataFrame, cols=:; disallowmissing::Bool=true)

Удаляет строки с отсутствующими значениями из фрейма данных df и возвращает его.

Если указано значение cols, учитываются только отсутствующие значения в соответствующих столбцах. cols может представлять собой любой селектор столбцов (символ (Symbol), строку или целое число; :, Cols, All, Between, Not, регулярное выражение или вектор символов (Symbol), строк или целых чисел).

Если disallowmissing имеет значение true (по умолчанию), столбцы cols преобразуются с помощью disallowmissing!.

Метаданные: эта функция сохраняет метаданные на уровне таблиц и столбцов в стиле :note.

См. также описание dropmissing и completecases.

julia> df = DataFrame(i=1:5,
                      x=[missing, 4, missing, 2, 1],
                      y=[missing, missing, "c", "d", "e"])
5×3 DataFrame
 Row │ i      x        y
     │ Int64  Int64?   String?
─────┼─────────────────────────
   1 │     1  missing  missing
   2 │     2        4  missing
   3 │     3  missing  c
   4 │     4        2  d
   5 │     5        1  e

julia> dropmissing!(copy(df))
2×3 DataFrame
 Row │ i      x      y
     │ Int64  Int64  String
─────┼──────────────────────
   1 │     4      2  d
   2 │     5      1  e

julia> dropmissing!(copy(df), disallowmissing=false)
2×3 DataFrame
 Row │ i      x       y
     │ Int64  Int64?  String?
─────┼────────────────────────
   1 │     4       2  d
   2 │     5       1  e

julia> dropmissing!(copy(df), :x)
3×3 DataFrame
 Row │ i      x      y
     │ Int64  Int64  String?
─────┼───────────────────────
   1 │     2      4  missing
   2 │     4      2  d
   3 │     5      1  e

julia> dropmissing!(df, [:x, :y])
2×3 DataFrame
 Row │ i      x      y
     │ Int64  Int64  String
─────┼──────────────────────
   1 │     4      2  d
   2 │     5      1  e

Итерация

# Base.eachcolFunction

eachcol(df::AbstractDataFrame)

Возвращает объект DataFrameColumns, подобный вектору, который позволяет итерировать AbstractDataFrame по столбцам.

Индексирование в объектах DataFrameColumns с использованием целого числа, Symbol или строки возвращает соответствующий столбец (без копирования). Индексирование в объектах DataFrameColumns с использованием селектора нескольких столбцов возвращает являющийся подмножеством объект DataFrameColumns с новым родителем, содержащим только выбранные столбцы (без копирования).

DataFrameColumns поддерживает большую часть API AbstractVector. Основные отличия заключаются в том, что он доступен только для чтения и функция keys возвращает вектор символов (Symbol) (а не целых чисел, как для обычных векторов).

В частности, поддерживаются функции findnext, findprev, findfirst, findlast и findall, и в функциях findnext и findprev разрешается передавать целое число, строку или символ (Symbol) в качестве эталонного индекса.

Примеры

julia> df = DataFrame(x=1:4, y=11:14)
4×2 DataFrame
 Row │ x      y
     │ Int64  Int64
─────┼──────────────
   1 │     1     11
   2 │     2     12
   3 │     3     13
   4 │     4     14

julia> eachcol(df)
4×2 DataFrameColumns
 Row │ x      y
     │ Int64  Int64
─────┼──────────────
   1 │     1     11
   2 │     2     12
   3 │     3     13
   4 │     4     14

julia> collect(eachcol(df))
2-element Vector{AbstractVector}:
 [1, 2, 3, 4]
 [11, 12, 13, 14]

julia> map(eachcol(df)) do col
           maximum(col) - minimum(col)
       end
2-element Vector{Int64}:
 3
 3

julia> sum.(eachcol(df))
2-element Vector{Int64}:
 10
 50

# Base.eachrowFunction

eachrow(df::AbstractDataFrame)

Возвращает DataFrameRows, который построчно итерирует фрейм данных, где каждая строка представлена как DataFrameRow.

Поскольку DataFrameRow имеют тип элемента (eltype) Any, используйте copy(dfr::DataFrameRow), чтобы получить именованный кортеж, который поддерживает итерацию и доступ к свойствам, как DataFrameRow, но также передает информацию о типах элементов (eltypes) столбцов df.

Примеры

julia> df = DataFrame(x=1:4, y=11:14)
4×2 DataFrame
 Row │ x      y
     │ Int64  Int64
─────┼──────────────
   1 │     1     11
   2 │     2     12
   3 │     3     13
   4 │     4     14

julia> eachrow(df)
4×2 DataFrameRows
 Row │ x      y
     │ Int64  Int64
─────┼──────────────
   1 │     1     11
   2 │     2     12
   3 │     3     13
   4 │     4     14

julia> copy.(eachrow(df))
4-element Vector{NamedTuple{(:x, :y), Tuple{Int64, Int64}}}:
 (x = 1, y = 11)
 (x = 2, y = 12)
 (x = 3, y = 13)
 (x = 4, y = 14)

julia> eachrow(view(df, [4, 3], [2, 1]))
2×2 DataFrameRows
 Row │ y      x
     │ Int64  Int64
─────┼──────────────
   1 │    14      4
   2 │    13      3

# Base.valuesFunction

values(dfc::DataFrameColumns)

Получает вектор столбцов из dfc.

# Base.pairsFunction

pairs(dfc::DataFrameColumns)

Возвращает итератор пар, связывающих имя каждого столбца dfc соответствующим вектором столбцов, т. е. name => col, где name — имя столбца col.

# Base.Iterators.partitionFunction

Iterators.partition(df::AbstractDataFrame, n::Integer)

Выполняет итерацию по фрейму данных df по n строк за раз, возвращая каждый блок в виде SubDataFrame.

Примеры

julia> collect(Iterators.partition(DataFrame(x=1:5), 2))
3-element Vector{SubDataFrame{DataFrame, DataFrames.Index, UnitRange{Int64}}}:
 2×1 SubDataFrame
 Row │ x
     │ Int64
─────┼───────
   1 │     1
   2 │     2
 2×1 SubDataFrame
 Row │ x
     │ Int64
─────┼───────
   1 │     3
   2 │     4
 1×1 SubDataFrame
 Row │ x
     │ Int64
─────┼───────
   1 │     5
Iterators.partition(dfr::DataFrameRows, n::Integer)

Выполняет итерацию по фрейму данных dfr DataFrameRows по n строк за раз, возвращая каждый блок в виде DataFrameRows в представлении строк родителя dfr.

Примеры

julia> collect(Iterators.partition(eachrow(DataFrame(x=1:5)), 2))
3-element Vector{DataFrames.DataFrameRows{SubDataFrame{DataFrame, DataFrames.Index, UnitRange{Int64}}}}:
 2×1 DataFrameRows
 Row │ x
     │ Int64
─────┼───────
   1 │     1
   2 │     2
 2×1 DataFrameRows
 Row │ x
     │ Int64
─────┼───────
   1 │     3
   2 │     4
 1×1 DataFrameRows
 Row │ x
     │ Int64
─────┼───────
   1 │     5

Равенство

# Base.isapproxFunction

isapprox(df1::AbstractDataFrame, df2::AbstractDataFrame;
         rtol::Real=atol>0 ? 0 : √eps, atol::Real=0,
         nans::Bool=false, norm::Function=norm)

Неточное сравнение на равенство. df1 и df2 должны иметь одинаковый размер и имена столбцов. Возвращает true, если isapprox с заданными именованными аргументами, примененными ко всем парам столбцов, хранящихся в df1 и df2, возвращает true.

Метаданные

# DataAPI.metadataFunction

metadata(df::AbstractDataFrame, key::AbstractString, [default]; style::Bool=false)
metadata(dfr::DataFrameRow, key::AbstractString, [default]; style::Bool=false)
metadata(dfc::DataFrameColumns, key::AbstractString, [default]; style::Bool=false)
metadata(dfr::DataFrameRows, key::AbstractString, [default]; style::Bool=false)

Return table-level metadata value associated with df for key key. If style=true return a tuple of metadata value and metadata style.

SubDataFrame and DataFrameRow expose only :note-style metadata of their parent.

If default is passed then return it if key does not exist; if style=true return (default, :default).

Examples

julia> df = DataFrame(a=1, b=2);

julia> metadatakeys(df)
()

julia> metadata!(df, "name", "example", style=:note);

julia> metadatakeys(df)
KeySet for a Dict{String, Tuple{Any, Any}} with 1 entry. Keys:
  "name"

julia> metadata(df, "name")
"example"

julia> metadata(df, "name", style=true)
("example", :note)

julia> deletemetadata!(df, "name");

julia> metadatakeys(df)
()

# DataAPI.metadatakeysFunction

metadatakeys(df::AbstractDataFrame)
metadatakeys(dfr::DataFrameRow)
metadatakeys(dfc::DataFrameColumns)
metadatakeys(dfr::DataFrameRows)

Return an iterator of table-level metadata keys which are set in the object.

Values can be accessed using metadata(df, key).

SubDataFrame and DataFrameRow expose only :note-style metadata keys of their parent.

Examples

julia> df = DataFrame(a=1, b=2);

julia> metadatakeys(df)
()

julia> metadata!(df, "name", "example", style=:note);

julia> metadatakeys(df)
KeySet for a Dict{String, Tuple{Any, Any}} with 1 entry. Keys:
  "name"

julia> metadata(df, "name")
"example"

julia> metadata(df, "name", style=true)
("example", :note)

julia> deletemetadata!(df, "name");

julia> metadatakeys(df)
()

# DataAPI.metadata!Function

metadata!(df::AbstractDataFrame, key::AbstractString, value; style::Symbol=:default)
metadata!(dfr::DataFrameRow, key::AbstractString, value; style::Symbol=:default)
metadata!(dfc::DataFrameColumns, key::AbstractString, value; style::Symbol=:default)
metadata!(dfr::DataFrameRows, key::AbstractString, value; style::Symbol=:default)

Set table-level metadata for object df for key key to have value value and style style (:default by default) and return df.

For SubDataFrame and DataFrameRow only :note-style is allowed. Trying to set a key-value pair for which the key already exists in the parent data frame with another style throws an error.

Examples

julia> df = DataFrame(a=1, b=2);

julia> metadatakeys(df)
()

julia> metadata!(df, "name", "example", style=:note);

julia> metadatakeys(df)
KeySet for a Dict{String, Tuple{Any, Any}} with 1 entry. Keys:
  "name"

julia> metadata(df, "name")
"example"

julia> metadata(df, "name", style=true)
("example", :note)

julia> deletemetadata!(df, "name");

julia> metadatakeys(df)
()

# DataAPI.deletemetadata!Function

deletemetadata!(df::AbstractDataFrame, key::AbstractString)
deletemetadata!(dfr::DataFrameRow, key::AbstractString)
deletemetadata!(dfc::DataFrameColumns, key::AbstractString)
deletemetadata!(dfr::DataFrameRows, key::AbstractString)

Delete table-level metadata from object df for key key and return df. If key does not exist, return df without modification.

For SubDataFrame and DataFrameRow only :note-style metadata from their parent can be deleted (as other styles are not propagated to views).

Examples

julia> df = DataFrame(a=1, b=2);

julia> metadatakeys(df)
()

julia> metadata!(df, "name", "example", style=:note);

julia> metadatakeys(df)
KeySet for a Dict{String, Tuple{Any, Any}} with 1 entry. Keys:
  "name"

julia> metadata(df, "name")
"example"

julia> metadata(df, "name", style=true)
("example", :note)

julia> deletemetadata!(df, "name");

julia> metadatakeys(df)
()

# DataAPI.emptymetadata!Function

emptymetadata!(df::AbstractDataFrame)
emptymetadata!(dfr::DataFrameRow)
emptymetadata!(dfc::DataFrameColumns)
emptymetadata!(dfr::DataFrameRows)

Delete all table-level metadata from object df.

For SubDataFrame and DataFrameRow only :note-style metadata from their parent can be deleted (as other styles are not propagated to views).

Examples

julia> df = DataFrame(a=1, b=2);

julia> metadatakeys(df)
()

julia> metadata!(df, "name", "example", style=:note);

julia> metadatakeys(df)
KeySet for a Dict{String, Tuple{Any, Any}} with 1 entry. Keys:
  "name"

julia> metadata(df, "name")
"example"

julia> metadata(df, "name", style=true)
("example", :note)

julia> emptymetadata!(df);

julia> metadatakeys(df)
()

# DataAPI.colmetadataFunction

colmetadata(df::AbstractDataFrame, col::ColumnIndex, key::AbstractString, [default]; style::Bool=false)
colmetadata(dfr::DataFrameRow, col::ColumnIndex, key::AbstractString, [default]; style::Bool=false)
colmetadata(dfc::DataFrameColumns, col::ColumnIndex, key::AbstractString, [default]; style::Bool=false)
colmetadata(dfr::DataFrameRows, col::ColumnIndex, key::AbstractString, [default]; style::Bool=false)

Return column-level metadata value associated with df for column col and key key.

SubDataFrame and DataFrameRow expose only :note-style metadata of their parent.

If default is passed then return it if key does not exist for column col; if style=true return (default, :default). If col does not exist in df always throw an error.

Examples

julia> df = DataFrame(a=1, b=2);

julia> colmetadatakeys(df)
()

julia> colmetadata!(df, :a, "name", "example", style=:note);

julia> collect(colmetadatakeys(df))
1-element Vector{Pair{Symbol, Base.KeySet{String, Dict{String, Tuple{Any, Any}}}}}:
 :a => ["name"]

julia> colmetadatakeys(df, :a)
KeySet for a Dict{String, Tuple{Any, Any}} with 1 entry. Keys:
  "name"

julia> colmetadata(df, :a, "name")
"example"

julia> colmetadata(df, :a, "name", style=true)
("example", :note)

julia> deletecolmetadata!(df, :a, "name");

julia> colmetadatakeys(df)
()

# DataAPI.colmetadatakeysFunction

colmetadatakeys(df::AbstractDataFrame, [col::ColumnIndex])
colmetadatakeys(dfr::DataFrameRow, [col::ColumnIndex])
colmetadatakeys(dfc::DataFrameColumns, [col::ColumnIndex])
colmetadatakeys(dfr::DataFrameRows, [col::ColumnIndex])

If col is passed return an iterator of column-level metadata keys which are set for column col. If col is not passed return an iterator of col => colmetadatakeys(x, col) pairs for all columns that have metadata, where col are Symbol.

Values can be accessed using colmetadata(df, col, key).

SubDataFrame and DataFrameRow expose only :note-style metadata of their parent.

Examples

julia> df = DataFrame(a=1, b=2);

julia> colmetadatakeys(df)
()

julia> colmetadata!(df, :a, "name", "example", style=:note);

julia> collect(colmetadatakeys(df))
1-element Vector{Pair{Symbol, Base.KeySet{String, Dict{String, Tuple{Any, Any}}}}}:
 :a => ["name"]

julia> colmetadatakeys(df, :a)
KeySet for a Dict{String, Tuple{Any, Any}} with 1 entry. Keys:
  "name"

julia> colmetadata(df, :a, "name")
"example"

julia> colmetadata(df, :a, "name", style=true)
("example", :note)

julia> deletecolmetadata!(df, :a, "name");

julia> colmetadatakeys(df)
()

# DataAPI.colmetadata!Function

colmetadata!(df::AbstractDataFrame, col::ColumnIndex, key::AbstractString, value; style::Symbol=:default)
colmetadata!(dfr::DataFrameRow, col::ColumnIndex, key::AbstractString, value; style::Symbol=:default)
colmetadata!(dfc::DataFrameColumns, col::ColumnIndex, key::AbstractString, value; style::Symbol=:default)
colmetadata!(dfr::DataFrameRows, col::ColumnIndex, key::AbstractString, value; style::Symbol=:default)

Set column-level metadata in df for column col and key key to have value value and style style (:default by default) and return df.

For SubDataFrame and DataFrameRow only :note style is allowed. Trying to set a key-value pair for which the key already exists in the parent data frame with another style throws an error.

Examples

julia> df = DataFrame(a=1, b=2);

julia> colmetadatakeys(df)
()

julia> colmetadata!(df, :a, "name", "example", style=:note);

julia> collect(colmetadatakeys(df))
1-element Vector{Pair{Symbol, Base.KeySet{String, Dict{String, Tuple{Any, Any}}}}}:
 :a => ["name"]

julia> colmetadatakeys(df, :a)
KeySet for a Dict{String, Tuple{Any, Any}} with 1 entry. Keys:
  "name"

julia> colmetadata(df, :a, "name")
"example"

julia> colmetadata(df, :a, "name", style=true)
("example", :note)

julia> deletecolmetadata!(df, :a, "name");

julia> colmetadatakeys(df)
()

# DataAPI.deletecolmetadata!Function

deletecolmetadata!(df::AbstractDataFrame, col::ColumnIndex, key::AbstractString)
deletecolmetadata!(dfr::DataFrameRow, col::ColumnIndex, key::AbstractString)
deletecolmetadata!(dfc::DataFrameColumns, col::ColumnIndex, key::AbstractString)
deletecolmetadata!(dfr::DataFrameRows, col::ColumnIndex, key::AbstractString)

Delete column-level metadata set in df for column col and key key and return df.

For SubDataFrame and DataFrameRow only :note-style metadata from their parent can be deleted (as other styles are not propagated to views).

Examples

julia> df = DataFrame(a=1, b=2);

julia> colmetadatakeys(df)
()

julia> colmetadata!(df, :a, "name", "example", style=:note);

julia> collect(colmetadatakeys(df))
1-element Vector{Pair{Symbol, Base.KeySet{String, Dict{String, Tuple{Any, Any}}}}}:
 :a => ["name"]

julia> colmetadatakeys(df, :a)
KeySet for a Dict{String, Tuple{Any, Any}} with 1 entry. Keys:
  "name"

julia> colmetadata(df, :a, "name")
"example"

julia> colmetadata(df, :a, "name", style=true)
("example", :note)

julia> deletecolmetadata!(df, :a, "name");

julia> colmetadatakeys(df)
()

# DataAPI.emptycolmetadata!Function

emptycolmetadata!(df::AbstractDataFrame, [col::ColumnIndex])
emptycolmetadata!(dfr::DataFrameRow, [col::ColumnIndex])
emptycolmetadata!(dfc::DataFrameColumns, [col::ColumnIndex])
emptycolmetadata!(dfr::DataFrameRows, [col::ColumnIndex])

Delete column-level metadata set in df for column col and key key and return df.

For SubDataFrame and DataFrameRow only :note-style metadata from their parent can be deleted (as other styles are not propagated to views).

Examples

julia> df = DataFrame(a=1, b=2);

julia> colmetadata!(df, :a, "name", "example", style=:note);

julia> collect(colmetadatakeys(df))
1-element Vector{Pair{Symbol, Base.KeySet{String, Dict{String, Tuple{Any, Any}}}}}:
 :a => ["name"]

julia> colmetadatakeys(df, :a)
KeySet for a Dict{String, Tuple{Any, Any}} with 1 entry. Keys:
  "name"

julia> colmetadata(df, :a, "name")
"example"

julia> colmetadata(df, :a, "name", style=true)
("example", :note)

julia> emptycolmetadata!(df, :a);

julia> colmetadatakeys(df)
()