DataFrames.transform 在 Julia 中使用匿名函数指定目标变量
DataFrames.transform specifying target variable with anonymous function in Julia
我正在尝试将 transform
与匿名函数 (x -> uppercase.(x)
) 结合使用,并通过指定目标列名称 (:A
) 将新列存储为 "A"
.
如果我没有指定目标列变量(下面的第一个转换),新变量生成很好(即一个包含 5 个元素的向量)。但是,一旦我指定了目标列(下面的第二个转换),函数 return 就是 "a_function"
名称下的对向量。
如何使用包含具有 5 个元素(“A”到“E”)的 Vector 的新列 "A"
生成所需的 DataFrame?为什么下面的第二个转换 return 是一个名称与指定名称不同的对向量?
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(a = ["a", "b", "c", "d", "e"],
A = ["A", "B", "C", "D", "E"])
原因是运算符优先级,如果你写:
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 中的新形式,它允许您将函数作为目标列名称说明符传递(在本例中,转换是将源列名称大写)。当然在这种情况下它更长,但如果您以编程方式定义转换,它有时会很有用。
我正在尝试将 transform
与匿名函数 (x -> uppercase.(x)
) 结合使用,并通过指定目标列名称 (:A
) 将新列存储为 "A"
.
如果我没有指定目标列变量(下面的第一个转换),新变量生成很好(即一个包含 5 个元素的向量)。但是,一旦我指定了目标列(下面的第二个转换),函数 return 就是 "a_function"
名称下的对向量。
如何使用包含具有 5 个元素(“A”到“E”)的 Vector 的新列 "A"
生成所需的 DataFrame?为什么下面的第二个转换 return 是一个名称与指定名称不同的对向量?
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(a = ["a", "b", "c", "d", "e"],
A = ["A", "B", "C", "D", "E"])
原因是运算符优先级,如果你写:
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 中的新形式,它允许您将函数作为目标列名称说明符传递(在本例中,转换是将源列名称大写)。当然在这种情况下它更长,但如果您以编程方式定义转换,它有时会很有用。