julia DataFrame выбирает строки на основе значений одного столбца, принадлежащего набору - PullRequest
1 голос
/ 03 октября 2019

Используя DataFrame в Julia, я хочу выбирать строки на основе значения, взятого в столбце.

В следующем примере

using DataFrames, DataFramesMeta
DT = DataFrame(ID = [1, 1, 2,2,3,3, 4,4], x1 = rand(8))

Я хочу извлечь строки с идентификатором, принимающим значения 1 и 4. На данный момент я предложил это решение.

@where(DT, findall(x -> (x==4 || x==1), DT.ID))

При использовании только двух значений, это управляемо.

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

Любое более изящное решение, чтобы сделать этот выбор универсальным?

Дэмиен

Ответы [ 2 ]

1 голос
/ 03 октября 2019

Вот способ сделать это, используя стандартную индексацию DataFrames.jl и используя @where из DataFramesMeta.jl:

julia> DT
8×2 DataFrame
│ Row │ ID    │ x1        │
│     │ Int64 │ Float64   │
├─────┼───────┼───────────┤
│ 1   │ 1     │ 0.433397  │
│ 2   │ 1     │ 0.963775  │
│ 3   │ 2     │ 0.365919  │
│ 4   │ 2     │ 0.325169  │
│ 5   │ 3     │ 0.0495252 │
│ 6   │ 3     │ 0.637568  │
│ 7   │ 4     │ 0.391051  │
│ 8   │ 4     │ 0.436209  │

julia> DT[in([1,4]).(DT.ID), :]
4×2 DataFrame
│ Row │ ID    │ x1       │
│     │ Int64 │ Float64  │
├─────┼───────┼──────────┤
│ 1   │ 1     │ 0.433397 │
│ 2   │ 1     │ 0.963775 │
│ 3   │ 4     │ 0.391051 │
│ 4   │ 4     │ 0.436209 │

julia> @where(DT, in([1,4]).(:ID))
4×2 DataFrame
│ Row │ ID    │ x1       │
│     │ Int64 │ Float64  │
├─────┼───────┼──────────┤
│ 1   │ 1     │ 0.433397 │
│ 2   │ 1     │ 0.963775 │
│ 3   │ 4     │ 0.391051 │
│ 4   │ 4     │ 0.436209 │

В не критичном для производительности коде вы также можете использовать filter, что- по крайней мере, для меня это немного проще для восприятия (но у него есть недостаток: он медленнее, чем методы, рассмотренные выше):

julia> filter(row -> row.ID in [1,4], DT)
4×2 DataFrame
│ Row │ ID    │ x1       │
│     │ Int64 │ Float64  │
├─────┼───────┼──────────┤
│ 1   │ 1     │ 0.433397 │
│ 2   │ 1     │ 0.963775 │
│ 3   │ 4     │ 0.391051 │
│ 4   │ 4     │ 0.436209 │

Обратите внимание, что в подходе, который вы упоминаете в своем вопросе, вы можете опуститьDT перед ID следующим образом:

julia> @where(DT, findall(x -> (x==4 || x==1), :ID))
4×2 DataFrame
│ Row │ ID    │ x1       │
│     │ Int64 │ Float64  │
├─────┼───────┼──────────┤
│ 1   │ 1     │ 0.433397 │
│ 2   │ 1     │ 0.963775 │
│ 3   │ 4     │ 0.391051 │
│ 4   │ 4     │ 0.436209 │

(это прелесть DataFramesMeta.jl, который знает контекст DataFrame, на который вы хотите сослаться)

0 голосов
/ 04 октября 2019

связано с этой проблемой.

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

По моему примеру

 @where(DT, in([1,4,1]).(:ID))

все равно даст

4×2 DataFrame
│ Row │ ID    │ x1       │
│     │ Int64 │ Float64  │
├─────┼───────┼──────────┤
│ 1   │ 1     │ 0.433397 │
│ 2   │ 1     │ 0.963775 │
│ 3   │ 4     │ 0.391051 │
│ 4   │ 4     │ 0.436209 │

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

6×2 DataFrame
│ Row │ ID    │ x1       │
│     │ Int64 │ Float64  │
├─────┼───────┼──────────┤
│ 1   │ 1     │ 0.433397 │
│ 2   │ 1     │ 0.963775 │
│ 3   │ 4     │ 0.391051 │
│ 4   │ 4     │ 0.436209 │
│ 5   │ 1     │ 0.433397 │
│ 6   │ 1     │ 0.963775 │

Isэто можно сделать так?

...