Индексирование
Общие правила
Ниже описываются правила работы 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]-> возвращает группу, соответствующуюGroupKeykey(один из элементов вектора, возвращаемого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).