【问题标题】:DataFrames.transform specifying target variable with anonymous function in JuliaDataFrames.transform 在 Julia 中使用匿名函数指定目标变量
【发布时间】:2022-01-17 00:55:00
【问题描述】:

我正在尝试将 transform 与匿名函数 (x -> uppercase.(x)) 一起使用,并通过指定目标列名称 (:A) 将新列存储为 "A"

如果我没有指定目标列变量(下面的第一个转换),则可以正常生成新变量(即具有 5 个元素的向量)。但是,一旦我指定了目标列(下面的第二个转换),该函数就会返回一个 "a_function" 名称下的向量对。

如何使用包含 5 个元素(“A”到“E”)的 Vector 的新列 "A" 生成所需的 DataFrame?为什么下面的第二个转换会返回一个名称与指定名称不同的向量对?

using DataFrames

df_1 = DataFrame(a = ["a", "b", "c", "d", "e"])

df_2 = transform(df_1, :a => x -> uppercase.(x))  # first transformation

df_2
 Row │ a       a_function 
     │ String  String
─────┼────────────────────
   1 │ a       A
   2 │ b       B
   3 │ c       C
   4 │ d       D
   5 │ e       E


df_3 = transform(df_1, :a => x -> uppercase.(x) => :A) # second transformation

df_3
5×2 DataFrame
 Row │ a       a_function
     │ String  Pair…
─────┼───────────────────────────────────────
   1 │ a       ["A", "B", "C", "D", "E"]=>:A
   2 │ b       ["A", "B", "C", "D", "E"]=>:A
   3 │ c       ["A", "B", "C", "D", "E"]=>:A
   4 │ d       ["A", "B", "C", "D", "E"]=>:A
   5 │ e       ["A", "B", "C", "D", "E"]=>:A

期望的结果DataFrame:

 DataFrame(a = ["a", "b", "c", "d", "e"],
    A = ["A", "B", "C", "D", "E"])

【问题讨论】:

    标签: julia transform anonymous-function dataframes.jl


    【解决方案1】:

    原因是运算符优先级,如果你写:

    julia> :a => x -> uppercase.(x) => :A
    :a => var"#7#8"()
    

    你看到你只定义了一对。整个uppercase.(x) => :A 部分成为您的匿名函数的主体。

    改为写(注意我在匿名函数周围添加了()):

    julia> :a => (x -> uppercase.(x)) => :A
    :a => (var"#9#10"() => :A)
    

    得到你想要的:

    julia> df_3 = transform(df_1, :a => (x -> uppercase.(x)) => :A)
    5×2 DataFrame
     Row │ a       A
         │ String  String
    ─────┼────────────────
       1 │ a       A
       2 │ b       B
       3 │ c       C
       4 │ d       D
       5 │ e       E
    

    在这种情况下,更标准的编写方式是:

    julia> transform(df_1, :a => ByRow(uppercase) => :A)
    5×2 DataFrame
     Row │ a       A
         │ String  String
    ─────┼────────────────
       1 │ a       A
       2 │ b       B
       3 │ c       C
       4 │ d       D
       5 │ e       E
    

    甚至:

    julia> transform(df_1, :a => ByRow(uppercase) => uppercase)
    5×2 DataFrame
     Row │ a       A
         │ String  String
    ─────┼────────────────
       1 │ a       A
       2 │ b       B
       3 │ c       C
       4 │ d       D
       5 │ e       E
    

    最后一种形式是 DataFrames.jl 1.3 中的新形式,它允许您将函数作为目标列名称说明符传递(在这种情况下,转换是将源列名称大写)。当然在这种情况下它会更长,但如果您以编程方式定义转换,它有时会很有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-17
      • 1970-01-01
      • 1970-01-01
      • 2012-12-17
      • 2012-07-10
      • 2015-12-03
      • 2023-01-12
      相关资源
      最近更新 更多