【问题标题】:Is there a package in Julia similar to dplyr?Julia 中是否有类似于 dplyr 的软件包?
【发布时间】:2022-10-16 02:38:49
【问题描述】:

假设我有以下数据框:

using DataFrames
a = DataFrame(A = randn(1000), B = randn(1000), C = randn(1000));
N = 1000;

就像我想将每一列除以 N(如果它是数字),所以在 R 中我会执行以下操作(使用 dplyr):

a <- a %>% mutate_if(is.numeric, function(x) x/N)

朱莉娅有这样的东西吗?

(我试图避免 for 循环,并逐列进行操作)

【问题讨论】:

    标签: dataframe julia


    【解决方案1】:

    DataFrames 文档有一个Comparison with dplyr 部分。您可以看到 dplyr 中的 mutates 对应于 DataFrames.jl 中的 transforms。 transform 还允许通过多种方式选择要操作的列,可用于mutate_if 功能。

    julia> df = DataFrame(x = [10, 15, 20, 25], y = [12.5, 20, 101, 102], colors = [:red, :blue, :green, :cyan])
    
    4×3 DataFrame
     Row │ x      y        colors 
         │ Int64  Float64  Symbol 
    ─────┼────────────────────────
       1 │    10     12.5  red
       2 │    15     20.0  blue
       3 │    20    101.0  green
       4 │    25    102.0  cyan
    
    julia> transform(df, names(df, Number) .=> (c -> c / 5) => identity)
    4×3 DataFrame
     Row │ x        y        colors 
         │ Float64  Float64  Symbol 
    ─────┼──────────────────────────
       1 │     2.0      2.5  red
       2 │     3.0      4.0  blue
       3 │     4.0     20.2  green
       4 │     5.0     20.4  cyan
    

    names(df, Number) 返回元素为 Numbers 的列名称的向量(即任何 Number 子类型)。
    c -&gt; c / 5 将列除以 5(Julia 默认按元素应用)。
    .=&gt; 对每一列单独应用上述转换,而不是一起应用。
    identity 只是告诉 transform 不要更改列的名称。

    (此答案之前建议将 transform(df, Cols(in(names(df, Number))) =&gt; ByRow((c...) -&gt; c ./ 5) =&gt; identity) 作为解决方案。感谢 cmets 中的 @Bogumił Kamiński 提出了当前更简单的方法。)

    上面的transform 返回结果数据帧,而不更改df。您可以使用
    transform!(df, names(df, Number) .=&gt; (c -&gt; c / 5) =&gt; identity)
    (注意transform 之后的!)就地执行此操作并直接更新df

    【讨论】:

    • transform(df, names(df, Number) .=&gt; ByRow(c -&gt; c / 5) .=&gt; identity) 会短一点。
    • 这要整洁得多。如果您不介意,我想用该建议更新答案。这样做ByRow 在这里有什么优势吗?在我的回答中,我使用它是因为我想保持函数非常简单且无需迭代,但在这种情况下,广播会满足这一需求。所以transform(df, names(df, Number) .=&gt; (c -&gt; c / 5) .=&gt; identity) 本身可以工作。
    【解决方案2】:

    transform 非常强大,如果您来自 dplyr 背景,它可能会感觉更自然,但我使用简单的列循环和更自然的项目广播来填充这种情况。

    不要害怕 Julia 中的循环:它们(一般而言)与矢量化代码一样快,并且可以使用数组理解非常简洁地编写:

    julia> df = DataFrame(x = [10, missing, 20, 25], y = [12.5, 20, 101, 102], colors = [:red, :blue, missing, :cyan])
    4×3 DataFrame
     Row │ x        y        colors  
         │ Int64?   Float64  Symbol? 
    ─────┼───────────────────────────
       1 │      10     12.5  red
       2 │ missing     20.0  blue
       3 │      20    101.0  missing 
       4 │      25    102.0  cyan
    
    julia> [c .= c ./ 5 for c in eachcol(df) if nonmissingtype(eltype(c)) <: Number];
    
    julia> df
    4×3 DataFrame
     Row │ x        y        colors  
         │ Int64?   Float64  Symbol? 
    ─────┼───────────────────────────
       1 │       2      2.5  red
       2 │ missing      4.0  blue
       3 │       4     20.2  missing 
       4 │       5     20.4  cyan
    

    在上面的例子中,点表示广播(c 列的每个元素是旧值除以标量 5 的结果),我使用nonmissingtype 来说明您可能有缺失数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-03
      • 2016-02-24
      • 2021-04-02
      • 1970-01-01
      • 2015-04-20
      • 1970-01-01
      相关资源
      最近更新 更多