Индексирование
Общие правила
Ниже описываются правила работы getindex
, setindex!
, view
и трансляции с объектами DataFrame
, SubDataFrame
и DataFrameRow
.
Допустимым индексом столбца является одно из следующих значений:
-
скаляр, далее обозначаемый как
col
:-
Symbol
; -
AbstractString
; -
Integer
, но неBool
;
-
-
вектор, далее обозначаемый как
cols
:-
вектор значений типа
Symbol
(необязательно подтипAbstractVector{Symbol}
); -
вектор значений типа
AbstractString
(необязательно подтипAbstractVector{<:AbstractString}
); -
вектор значений типа
Integer
, но неBool
(необязательно подтипAbstractVector{<:Integer}
); -
вектор значений типа
Bool
(должен быть подтипомAbstractVector{Bool}
); -
регулярное выражение (развертывается в вектор соответствующих имен столбцов);
-
выражение
Not
(см. пакет InvertedIndices.jl);Not(idx)
выбирает все индексы, которых нет в переданномidx
; при передаче в качестве селектора столбцовNot(idx...)
эквивалентноNot(Cols(idx...))
. -
выражение
Cols
(см. пакет DataAPI.jl);Cols(idxs...)
выбирает объединение выбранных вidxs
столбцов; в частности,Cols()
не выбирает ни один столбец, аCols(:)
выбирает все столбцы; особым случаем являетсяCols(predicate)
, гдеpredicate
— это предикативная функция; в этом случае выбираются столбцы, для имен которых, переданных вpredicate
в виде строк, возвращаетсяtrue
; -
выражение
Between
(см. пакет DataAPI.jl);Between(first, last)
выбирает столбцы отfirst
доlast
включительно; -
выражение
All
(см. пакет DataAPI.jl);All()
выбирает все столбцы, что равносильно:
; -
литерал двоеточия
:
(выбирает все столбцы).
-
Допустимым индексом строки является одно из следующих значений:
-
скаляр, далее обозначаемый как
row
:-
Integer
, но неBool
;
-
-
вектор, далее обозначаемый как
rows
:-
вектор значений типа
Integer
, но неBool
(необязательно подтипAbstractVector{<:Integer}
); -
вектор значений типа
Bool
(должен быть подтипомAbstractVector{Bool}
); -
выражение
Not
(см. пакет InvertedIndices.jl); -
литерал двоеточия
:
(выбирает все строки с копированием); -
литерал восклицательного знака
!
(выбирает все строки без копирования).
-
Кроме того, допускается индексация объекта AbstractDataFrame
с использованием двухмерного объекта CartesianIndex
.
В описаниях ниже df
представляет объект DataFrame
, sdf
— объект SubDataFrame
, а dfr
— объект DataFrameRow
.
:
всегда расширяется до axes(df, 1)
или axes(sdf, 1)
.
df.col
во всех случаях работает так же, как df[!, col]
, а sdf.col
— так же, как sdf[!, col]
. Однако в версии Julia 1.6 и более ранних есть одно исключение: df.col .= v
и sdf.col .= v
выполняют трансляцию на месте, если col
имеется в df
или sdf
и является допустимым именем (эта несогласованность устранена в версии Julia 1.7 и более поздних).
getindex
и view
В приведенном ниже списке описывается поведение операций getindex
и view
в зависимости от типов аргументов.
В частности, явно указывается, копируются ли данные или используются повторно без копирования.
Из соображений производительности при доступе к одной строке row
и нескольким столбцам cols
объекта DataFrame
, SubDataFrame
или DataFrameRow
посредством getindex
или view
всегда возвращается DataFrameRow
(то есть тип представления).
Вызов getindex
для DataFrame
:
-
df[row, col]
-> значение, содержащееся в строкеrow
в столбцеcol
; то же, что иdf[!, col][row]
; -
df[CartesianIndex(row, col)]
-> равносильноdf[row, col]
; -
df[row, cols]
-> объектDataFrameRow
с родительским объектомdf
; -
df[rows, col]
-> копия вектораdf[!, col]
, которая содержит только те элементы, которые соответствуют выбранным строкамrows
; равносильноdf[!, col][rows]
; -
df[rows, cols]
-> объектDataFrame
с копиями столбцовcols
, которые содержат только те элементы, которые соответствуют выбранным строкамrows
; -
df[!, col]
-> вектор, содержащийся в столбцеcol
и возвращаемый без копирования; равносильноdf.col
, еслиcol
— это допустимое имя; -
df[!, cols]
-> создает новый объектDataFrame
со столбцамиcols
без копирования столбцов; равносильноselect(df, cols, copycols=false)
.
Вызов view
для DataFrame
:
-
@view df[row, col]
->0
-мерное представлениеdf[!, col]
по строкеrow
; равносильноview(df[!, col], row)
; -
@view df[CartesianIndex(row, col)]
-> равносильно@view df[row, col]
; -
@view df[row, cols]
-> равносильноdf[row, cols]
; -
@view df[rows, col]
-> представлениеdf[!, col]
с выбранными строкамиrows
; равносильноview(df[!, col], rows)
; -
@view df[rows, cols]
-> объектSubDataFrame
с выбранными строкамиrows
и родительским объектомdf
; -
@view df[!, col]
-> представлениеdf[!, col]
со всеми строками; -
@view df[!, cols]
-> равносильно@view df[:, cols]
.
Вызов getindex
для SubDataFrame
:
-
sdf[row, col]
-> значение, содержащееся в строкеrow
в столбцеcol
; -
sdf[CartesianIndex(row, col)]
-> равносильноsdf[row, col]
; -
sdf[row, cols]
-> объектDataFrameRow
с родительским объектомparent(sdf)
; -
sdf[rows, col]
-> копияsdf[!, col]
только с выбранными строкамиrows
; равносильноsdf[!, col][rows]
; -
sdf[rows, cols]
-> объектDataFrame
, содержащий столбцыcols
иsdf[rows, col]
в качестве вектора для каждого столбцаcol
вcols
; -
sdf[!, col]
-> представление из элементов, соответствующихsdf
в вектореparent(sdf)[!, col]
; равносильноsdf.col
, еслиcol
— это допустимое имя; -
sdf[!, cols]
-> создает новый объектSubDataFrame
со столбцамиcols
, тем же родительским объектом, что и уsdf
, и теми же выбранными строками; равносильноselect(sdf, cols, copycols=false)
.
Вызов view
для SubDataFrame
:
-
@view sdf[row, col]
->0
-мерное представлениеdf[!, col]
по строкеrow
; равносильноview(sdf[!, col], row)
; -
@view sdf[CartesianIndex(row, col)]
-> равносильно@view sdf[row, col]
; -
@view sdf[row, cols]
-> объектDataFrameRow
с родительским объектомparent(sdf)
; -
@view sdf[rows, col]
-> представление вектораsdf[!, col]
с выбранными строкамиrows
; равносильноview(sdf[!, col], rows)
; -
@view sdf[rows, cols]
-> объектSubDataFrame
с родительским объектомparent(sdf)
; -
@view sdf[!, col]
-> представление вектораsdf[!, col]
со всеми строками; -
@view sdf[!, cols]
-> равносильно@view sdf[:, cols]
.
Вызов getindex
для DataFrameRow
:
-
dfr[col]
-> значение, содержащееся в столбцеcol
объектаdfr
; равносильноdfr.col
, еслиcol
— это допустимое имя; -
dfr[cols]
-> объектDataFrameRow
с родительским объектомparent(dfr)
.
Вызов view
для DataFrameRow
:
-
@view dfr[col]
->0
-мерное представлениеparent(dfr)[DataFrames.row(dfr), col]
; -
@view dfr[cols]
-> объектDataFrameRow
с родительским объектомparent(dfr)
.
Обратите внимание, что число столбцов в представлениях, создаваемых с селектором столбцов :
, изменяется при добавлении, удалении или переименовании столбцов в родительском объекте. Если селектор столбцов отличается от :
, то представление ссылается на то количество выбранных столбцов, которое имелось на момент его создания.
setindex!
В приведенном ниже списке описывается поведение операций setindex!
в зависимости от типов аргументов.
В частности, явно указывается, производится ли присваивание на месте.
Обратите внимание: если операция setindex!
выдает ошибку, целевой фрейм данных может оказаться частично измененным, поэтому дальнейшее его использование небезопасно (правильность длин столбцов сохраняется).
Вызов setindex!
для DataFrame
:
-
df[row, col] = v
-> элементу в столбцеcol
в строкеrow
присваивается значениеv
на месте; -
df[CartesianIndex(row, col)] = v
-> равносильноdf[row, col] = v
; -
df[row, cols] = v
-> присваивает значение элементам в строкеrow
в столбцахcols
на месте; равносильноdfr = df[row, cols]; dfr[:] = v
; -
df[rows, col] = v
-> присваивает значение элементам в строкахrows
в столбцеcol
на месте;v
должно быть векторомAbstractVector
; если в качествеrows
передан литерал:
, а в качествеcol
— символSymbol
или строкаAbstractString
, которых нет вdf
, вdf
создается новый столбец, содержащий копию (copy
) значенияv
; равносильноdf.col = copy(v)
, еслиcol
— это допустимое имя; -
df[rows, cols] = v
-> присваивает значение элементам в строкахrows
и столбцахcols
на месте;v
должно быть матрицейAbstractMatrix
или фреймомAbstractDataFrame
(в этом случае имена столбцов должны совпадать); -
df[!, col] = v
-> заменяетcol
наv
без копирования (но еслиv
— это диапазонAbstractRange
, он преобразуется вVector
); кроме того, еслиcol
— это символSymbol
или строкаAbstractString
, которых нет вdf
, то вdf
создается новый столбец, содержащийv
; равносильноdf.col = v
, еслиcol
— это допустимое имя; допускается, еслиncol(df) == 0 || length(v) == nrow(df)
; -
df[!, cols] = v
-> заменяет существующие столбцыcols
во фрейме данныхdf
с копированием;v
должно быть матрицейAbstractMatrix
или фреймомAbstractDataFrame
(во втором случае имена столбцов должны совпадать);
Вызов setindex!
для SubDataFrame
:
-
sdf[row, col] = v
-> элементу в столбцеcol
в строкеrow
присваивается значениеv
на месте; -
sdf[CartesianIndex(row, col)] = v
-> равносильноsdf[row, col] = v
; -
sdf[row, cols] = v
-> равносильно операцииdfr = df[row, cols]; dfr[:] = v
на месте; -
sdf[rows, col] = v
-> присваивает значение элементам в строкахrows
в столбцеcol
на месте;v
должно быть абстрактным вектором; -
sdf[rows, cols] = v
-> присваивает значение элементам в строкахrows
и столбцахcols
на месте;v
может быть матрицейAbstractMatrix
или фреймомAbstractDataFrame
(в этом случае имена столбцов должны совпадать); -
sdf[!, col] = v
-> заменяетcol
наv
без копирования; если столбецcol
имеется вsdf
, то отфильтрованные строки в создаваемом векторе заполняются значениями, уже имеющимися в этом столбце, аpromote_type
используется для определения типаeltype
нового столбца; если столбецcol
отсутствует вsdf
, то эта операция допустима только в том случае, если объектsdf
был создан с литералом:
в качестве селектора столбцов, и в таком случае отфильтрованные строки заполняются значениемmissing
; равносильноsdf.col = v
, еслиcol
— это допустимое имя; данная операция допустима, еслиlength(v) == nrow(sdf)
; -
sdf[!, cols] = v
-> заменяет существующие столбцыcols
во фрейме данныхsdf
с копированием;v
должно быть матрицейAbstractMatrix
или фреймомAbstractDataFrame
(во втором случае имена столбцов должны совпадать); отфильтрованные строки в создаваемых векторах заполняются значениями, уже имеющимися в соответствующих столбцах, аpromote_type
используется для определения типаeltype
новых столбцов.
Приведенные выше правила означают, что |
Вызов setindex!
для DataFrameRow
:
-
dfr[col] = v
-> элементу в столбцеcol
в строкеrow
присваивается значениеv
на месте; равносильноdfr.col = v
, еслиcol
— это допустимое имя; -
dfr[cols] = v
-> элементам в столбцахcols
объектаdfr
присваиваются значения элементовv
на месте;v
может иметь один из следующих типов: 1) кортежTuple
или массивAbstractArray
, количество элементов которого должно быть равноlength(dfr)
; 2) словарьAbstractDict
; в этом случае имена должны совпадать; 3) кортежNamedTuple
или объектDataFrameRow
; в этом случае имена и порядок столбцов должны совпадать.
Трансляция
Для объектов AbstractDataFrame
действуют следующие правила трансляции.
-
AbstractDataFrame
ведет себя при трансляции как двухмерная коллекция, совместимая с матрицами. -
Если объект
AbstractDataFrame
участвует в трансляции, то результатом всегда будетDataFrame
. В этом случае запрошенная операция трансляции всегда возвращает объект ровно с двумя измерениями. Исключением является ситуация, когдаAbstractDataFrame
используется только в качестве источника присваивания с трансляцией объекту с размерностью более двух. -
Если в трансляции участвует несколько объектов
AbstractDataFrame
, то они должны иметь идентичные имена столбцов.
Обратите внимание: если операция присваивания с трансляцией выдает ошибку, целевой фрейм данных может оказаться частично измененным, поэтому дальнейшее его использование небезопасно (правильность длин столбцов сохраняется).
Трансляция DataFrameRow
в настоящее время не допускается (что согласуется с NamedTuple
).
Объектам AbstractDataFrame
и DataFrameRow
значения можно присваивать с помощью оператора .=
. При такой операции объект AbstractDataFrame
считается двухмерным, а DataFrameRow
— одномерным.
Приведенное выше правило означает, что, как и в случае с одномерными объектами в модуле Base (например, векторами), объект |
Дополнительные правила
-
В синтаксических конструкциях
df[CartesianIndex(row, col)] .= v
иdf[row, col] .= v
значениеv
транслируется в содержимоеdf[row, col]
(это согласуется с поведением, принятым в модуле Julia Base). -
В синтаксических конструкциях
df[row, cols] .= v
присваивание значения объектуdf
выполняется на месте. -
В синтаксических конструкциях
df[rows, col] .= v
иdf[rows, cols] .= v
присваивание значения объектуdf
выполняется на месте. Если в качествеrows
передан литерал:
, а в качествеcol
— символSymbol
или строкаAbstractString
, которые отсутствуют вdf
, то новый столбец размещается в памяти и добавляется. Длина столбца всегда равнаnrow(df)
перед присваиванием. -
В синтаксической конструкции
df[!, col] .= v
столбецcol
заменяется новым размещенным в памяти вектором. Если в качествеcol
передан символSymbol
или строкаAbstractString
, которые отсутствуют вdf
, то новый столбец размещается в памяти и добавляется. Длина столбца всегда равнаnrow(df)
перед присваиванием. -
Синтаксическая конструкция
df[!, cols] .= v
заменяет существующие столбцыcols
во фрейме данныхdf
новыми размещенными в памяти векторами. -
Синтаксическая конструкция
df.col .= v
в настоящее время выполняет присваивание значения на месте существующему векторуdf.col
. Такое поведение считается устаревшим, и в будущем в памяти будет размещаться новый столбец. Начиная с версии Julia 1.7, если:col
отсутствует вdf
, то вdf
создается новый столбец. -
В синтаксических конструкциях
sdf[CartesianIndex(row, col)] .= v
,sdf[row, col] .= v
иsdf[row, cols] .= v
присваивание значения объектуsdf
выполняется на месте. -
В синтаксических конструкциях
sdf[rows, col] .= v
иsdf[rows, cols] .= v
присваивание значения объектуsdf
выполняется на месте. Если в качествеrows
передан литерал:
, а в качествеcol
— символSymbol
или строкаAbstractString
, ссылающиеся на столбец, которого нет вsdf
, и объектsdf
был создан с литералом:
в качестве селектора столбцов, то новый столбец размещается в памяти и добавляется. Отфильтрованные строки заполняются значениемmissing
. -
В синтаксической конструкции
sdf[!, col] .= v
столбецcol
заменяется новым размещенным в памяти вектором. Отфильтрованные строки заполняются значениями, уже имеющимися в столбцеcol
. Если в качествеcol
передан символSymbol
или строкаAbstractString
, ссылающиеся на столбец, которого нет вsdf
, и объектsdf
был создан с литералом:
в качестве селектора столбцов, то новый столбец размещается в памяти и добавляется. В этом случае отфильтрованные строки заполняются значениемmissing
. -
Синтаксическая конструкция
sdf[!, cols] .= v
заменяет существующие столбцыcols
во фрейме данныхsdf
новыми размещенными в памяти векторами. Отфильтрованные строки заполняются значениями, уже имеющимися вcols
. -
Синтаксическая конструкция
sdf.col .= v
в настоящее время выполняет присваивание значения на месте существующему векторуsdf.col
. Такое поведение считается устаревшим, и в будущем в памяти будет размещаться новый столбец. Начиная с версии Julia 1.7, если:col
отсутствует вsdf
, то вsdf
создается новый столбец, если объектsdf
был создан с литералом:
в качестве селектора столбцов. -
Синтаксическая конструкция
dfr.col .= v
допустима и выполняет присваивание на месте значению, извлеченному с помощьюdfr.col
.
Обратите внимание, что синтаксические конструкции sdf[!, col] .= v
и sdf[!, cols] .= v
недопустимы, так как объект sdf
можно изменять только на месте.
При индексировании столбцов по именам типа Symbol
или AbstractString
в cols
порядок столбцов в операции определяется согласно порядку имен.
Индексирование объектов GroupedDataFrame
Объект GroupedDataFrame
может вести себя как AbstractVector
или AbstractDict
в зависимости от типа используемого индекса. Целочисленные индексы (или их массивы) приводят к векторному индексированию, а кортежи Tuples
и NamedTuple
— к индексированию наподобие словарей. Нечто среднее представляет собой тип GroupKey
, возвращаемый keys(::GroupedDataFrame)
. Он ведет себя так же, как NamedTuple
, но по производительности сопоставим с целочисленным индексированием.
Элементами фрейма GroupedDataFrame
являются объекты SubDataFrame
родительского объекта.
-
gd[i::Integer]
-> возвращаетi
-ю группу. -
gd[key::NamedTuple]
-> возвращает группу, соответствующую предоставленным значениям столбцов группировки. ПоляNamedTuple
должны соответствовать столбцам группировки, переданным вgroupby
(включая их порядок). -
gd[key::Tuple]
-> аналогично предыдущему вызову, но без указания имен вkey
. -
get(gd, key::Union{Tuple, NamedTuple}, default)
-> возвращает группу для ключаkey
илиdefault
, если такой группы нет. -
gd[key::GroupKey]
-> возвращает группу, соответствующуюGroupKey
key
(один из элементов вектора, возвращаемогоkeys(::GroupedDataFrame)
). Выполняется почти так же быстро, как целочисленное индексирование. -
gd[a::AbstractVector]
-> выбирает несколько групп и возвращает их в новом объектеGroupedDataFrame
. Группы могут выбираться по целочисленной позиции с помощью массива значений типаInteger
илиBool
, похожего на обычный массив. Массив может также содержать ключи любого из типов, поддерживаемых при индексировании словарей (GroupKey
,Tuple
илиNamedTuple
). Выбираемые группы должны быть уникальными. Разные типы индексов нельзя использовать вместе. -
gd[n::Not]
-> любой из приведенных выше типов, заключенный вNot
. Результатом будет новый объектGroupedDataFrame
, содержащий все группы вgd
, которые не выбираются заключенным вNot
индексом.
Общий API для типов, определенных в DataFrames.jl
В этой таблице представлены типы значений, которые возвращаются при вызове names
, propertynames
, keys
, length
и ndims
для типов, доступных пользователю в пакете DataFrames.jl:
Тип | names |
propertynames |
keys |
length |
ndims |
---|---|---|---|---|---|
|
|
|
не определено |
не определено |
|
|
|
|
|
|
|
|
|
|
вектор |
|
|
|
|
|
|
|
|
|
|
кортеж полей |
|
|
|
|
не определено |
кортеж полей |
вектор |
|
|
|
|
|
|
|
|
Кроме того, для приведенных выше типов T
(AbstractDataFrame
, DataFrameRow
, DataFrameRows
, DataFrameColumns
, GroupedDataFrame
, GroupKeys
, GroupKey
) определены следующие методы:
-
size(::T)
возвращает кортежTuple
значений типаInt
. -
size(::T, ::Integer)
возвращаетInt
. -
axes(::T)
возвращает кортежTuple
векторов типаInt
. -
axes(::T, ::Integer)
возвращает вектор типаInt
для допустимого измерения (кроме объектовDataFrameRows
иGroupKeys
, для которыхBase.OneTo(1)
также возвращается для измерения выше допустимого, поскольку они имеют типAbstractVector
). -
firstindex(::T)
возвращает1
(кроме объектаAbstractDataFrame
, для которого этот метод не определен). -
firstindex(::T, ::Integer)
возвращает1
для допустимого измерения (кроме объектовDataFrameRows
иGroupKeys
, для которых1
также возвращается для измерения выше допустимого, поскольку они имеют типAbstractVector
). -
lastindex(::T)
возвращаетInt
(кроме объектаAbstractDataFrame
, для которого этот метод не определен). -
lastindex(::T, ::Integer)
возвращаетInt
для допустимого измерения (кроме объектовDataFrameRows
иGroupKeys
, для которых1
также возвращается для измерения выше допустимого, поскольку они имеют типAbstractVector
).