我目前有一个Julia
数据框如下所示:
A | B |
---|---|
"[1,2]" | "[3,4]" |
我想把它转换成以下格式:
A1 | A2 | B1 | B2 |
---|---|---|---|
1 | 2 | 3 | 4 |
或者是这样的格式(其中向量不再是字符串)。
| A | B | |---|---| |[1,2]|[3,4]| 有没有什么办法可以做到这一点?我已经看了一些帖子,其中有人试图将形式为["1","2"]的向量转换为[1,2]的形式,但没有与我类似的内容。
谢谢你的帮助。
我目前有一个Julia
数据框如下所示:
A | B |
---|---|
"[1,2]" | "[3,4]" |
我想把它转换成以下格式:
A1 | A2 | B1 | B2 |
---|---|---|---|
1 | 2 | 3 | 4 |
或者是这样的格式(其中向量不再是字符串)。
| A | B | |---|---| |[1,2]|[3,4]| 有没有什么办法可以做到这一点?我已经看了一些帖子,其中有人试图将形式为["1","2"]的向量转换为[1,2]的形式,但没有与我类似的内容。
谢谢你的帮助。
julia> using DataFrames
julia> df = DataFrame(A="[1,2]", B="[3,4]")
1×2 DataFrame
Row │ A B
│ String String
─────┼────────────────
1 │ [1,2] [3,4]
julia> select(df, [:A, :B] .=>
ByRow(x -> parse.(Int, split(chop(x, head=1, tail=1), ','))) .=>
[[:A1, :A2], [:B1, :B2]])
1×4 DataFrame
Row │ A1 A2 B1 B2
│ Int64 Int64 Int64 Int64
─────┼────────────────────────────
1 │ 1 2 3 4
如果有需要解释的内容,请在评论中询问。
定义
# WARNING: `parsedf` parses/evaluates input text and
# is therefore an infosec weakness. Should be used only
# with properly vetted input.
parsedf(df) = DataFrame([c=>eval.(Meta.parse.(df[:,c]))
for c in names(df)])
spreaddf(df) = DataFrame([c*"$i" => get.(df[:, c],i,missing)
for (c, i) in vcat([[(names(df)[i],j)
for j=1:L]
for (i,L) in enumerate([maximum(length.(df[:,i]))
for i in 1:ncol(df)])]...)]...)
现在,
julia> df = DataFrame(A=["[1,2]"],B=["[3,4]"])
1×2 DataFrame
Row │ A B
│ String String
─────┼────────────────
1 │ [1,2] [3,4]
julia> spreaddf(parsedf(df))
1×4 DataFrame
Row │ A1 A2 B1 B2
│ Int64 Int64 Int64 Int64
─────┼────────────────────────────
1 │ 1 2 3 4
看起来做到了。
另外,
julia> spreaddf(parsedf(DataFrame(A=["[1,2]","[5,6]"], B=["[3,4]","[7,8,9]"])))
2×5 DataFrame
Row │ A1 A2 B1 B2 B3
│ Int64 Int64 Int64 Int64 Int64?
─────┼─────────────────────────────────────
1 │ 1 2 3 4 missing
2 │ 5 6 7 8 9
看起来很合适。
Meta.parse
。这几乎肯定是OP所要求的,但绝对不是他们应该要求的。使用通用解析器解析用户输入非常危险,即使在一次性情况下(因为这种代码往往超出预期)。请参见最近的log4j事件,以清楚地说明让这种事情进入代码库看似无害的例子。 - Ted Dunning