Как применить функции к Dataframe с массивами внутри него, в Julia? - PullRequest
4 голосов
/ 05 апреля 2020

Я надеюсь прояснить вопросы, но позвольте мне объяснить здесь лучше: у меня есть этот фрейм данных:

m = DataFrame(
x = [1,2,3],
y = [[1,2,3],[4,5,6],[7,8,9]])

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

m = DataFrame(
x = [1,2,3],
y = [[1,2,3],[4,5,6],[7,8,9]],
z = [[2,5,10],[18,27,38],[52,67,84]])

Я могу сделать это в R, используя этот код:

m <- m %>% mutate(z = map2(x,y, ~map2_dbl(.x,.y, ~ (.x + .y^2))))

Есть ли что-то подобное в Джулии? Привет

Ответы [ 2 ]

3 голосов
/ 05 апреля 2020

В мастере DataFrames.jl (который скоро будет выпущен) вы можете использовать функцию transform:

julia> using DataFrames

julia> m = DataFrame(x = [1,2,3], y = [[1,2,3],[4,5,6],[7,8,9]])
3×2 DataFrame
│ Row │ x     │ y         │
│     │ Int64 │ Array…    │
├─────┼───────┼───────────┤
│ 1   │ 1     │ [1, 2, 3] │
│ 2   │ 2     │ [4, 5, 6] │
│ 3   │ 3     │ [7, 8, 9] │

julia> transform(m, [:x, :y] => ByRow((x,y) -> y.^2 .+ x) => :z)
3×3 DataFrame
│ Row │ x     │ y         │ z            │
│     │ Int64 │ Array…    │ Array…       │
├─────┼───────┼───────────┼──────────────┤
│ 1   │ 1     │ [1, 2, 3] │ [2, 5, 10]   │
│ 2   │ 2     │ [4, 5, 6] │ [18, 27, 38] │
│ 3   │ 3     │ [7, 8, 9] │ [52, 67, 84] │
2 голосов
/ 05 апреля 2020

Что-то вроде этого должно работать:

julia> using DataFrames

julia> m = DataFrame(
           x = [1,2,3],
           y = [[1,2,3],[4,5,6],[7,8,9]])
3×2 DataFrame
│ Row │ x     │ y         │
│     │ Int64 │ Array…    │
├─────┼───────┼───────────┤
│ 1   │ 1     │ [1, 2, 3] │
│ 2   │ 2     │ [4, 5, 6] │
│ 3   │ 3     │ [7, 8, 9] │

julia> m.z = map(eachrow(m)) do row
           row.x .+ row.y .^ 2
       end
3-element Array{Array{Int64,1},1}:
 [2, 5, 10]
 [18, 27, 38]
 [52, 67, 84]

julia> m
3×3 DataFrame
│ Row │ x     │ y         │ z            │
│     │ Int64 │ Array…    │ Array…       │
├─────┼───────┼───────────┼──────────────┤
│ 1   │ 1     │ [1, 2, 3] │ [2, 5, 10]   │
│ 2   │ 2     │ [4, 5, 6] │ [18, 27, 38] │
│ 3   │ 3     │ [7, 8, 9] │ [52, 67, 84] │

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

       # Define the function that works on one dataframe row
julia> f(x, y) = y.^2 .+ x
f (generic function with 1 method)

julia> f(1, [1,2,3])
3-element Array{Int64,1}:
  2
  5
 10

       # And broadcast (map) it to all rows
julia> m.z = f.(m.x, m.y)
3-element Array{Array{Int64,1},1}:
 [2, 5, 10]
 [18, 27, 38]
 [52, 67, 84]

julia> m
3×3 DataFrame
│ Row │ x     │ y         │ z            │
│     │ Int64 │ Array…    │ Array…       │
├─────┼───────┼───────────┼──────────────┤
│ 1   │ 1     │ [1, 2, 3] │ [2, 5, 10]   │
│ 2   │ 2     │ [4, 5, 6] │ [18, 27, 38] │
│ 3   │ 3     │ [7, 8, 9] │ [52, 67, 84] │
...