如何在Julia中对包含数组的Dataframe应用函数?

4

我希望能够清楚地回答问题,但让我在这里更好地解释一下:

我有这个数据框:

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

我的目标是获得列 z,该列为每个 y 数组的平方加上对应于列位置的 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))))

Julia里有类似的东西吗? 谢谢。

2个回答

3
在即将发布的 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…    │
├─────┼───────┼───────────┤
│ 11     │ [1, 2, 3] │
│ 22     │ [4, 5, 6] │
│ 33     │ [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…       │
├─────┼───────┼───────────┼──────────────┤
│ 11     │ [1, 2, 3] │ [2, 5, 10]   │
│ 22     │ [4, 5, 6] │ [18, 27, 38] │
│ 33     │ [7, 8, 9] │ [52, 67, 84] │

看起来很有趣。谢谢你!我只有一个问题,使用 "=>" 您是把它当作字典处理吗?问候 - Alí Meres Vargas
“=>” 应该被理解为链接,因此一个通用规则是 “source_columns => function => target_column_name”。 “ByRow” 表示传递的函数应该应用于数据框的每一行(而不是整个列)。 - Bogumił Kamiński
如果每列只有一个数字,而且你有成千上万个数字(即不想明确地给它们命名),那该怎么办? - Johan Dettmar
请问您能提出一个单独的问题吗?因为目前还不太清楚您需要什么。您可以使用任意列选择器作为输入,例如 All() 来选择所有列。 - Bogumił Kamiński

2

可以尝试以下方式:

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…    │
├─────┼───────┼───────────┤
│ 11     │ [1, 2, 3] │
│ 22     │ [4, 5, 6] │
│ 33     │ [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…       │
├─────┼───────┼───────────┼──────────────┤
│ 11     │ [1, 2, 3] │ [2, 5, 10]   │
│ 22     │ [4, 5, 6] │ [18, 27, 38] │
│ 33     │ [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…       │
├─────┼───────┼───────────┼──────────────┤
│ 11     │ [1, 2, 3] │ [2, 5, 10]   │
│ 22     │ [4, 5, 6] │ [18, 27, 38] │
│ 33     │ [7, 8, 9] │ [52, 67, 84] │

非常感谢您的回答。那真的很有帮助。 - Alí Meres Vargas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接