将字符串作为向量读取 Julia

4

我目前有一个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]的形式,但没有与我类似的内容。

谢谢你的帮助。

2个回答

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
─────┼────────────────────────────
   11      2      3      4

如果有需要解释的内容,请在评论中询问。


0

定义

# 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 
─────┼────────────────────────────
   11      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?  
─────┼─────────────────────────────────────
   11      2      3      4  missing 
   25      6      7      8        9

看起来很合适。


2
请注意,OP在源数据框的单元格中使用了字符串而不是向量。很可能OP将向量的向量保存到CSV数据框中,然后再读取它。实际上,最好使用Arrow.jl来保存这样的数据。 - Bogumił Kamiński
感谢@BogumiłKamiński指出缺失的OP细微差别。已经进行了修复(在信息安全方面相当危险,但这不是请求的一部分)。 - Dan Getz
值得强调@DanGetz关于信息安全的评论。这里的代码调用了Meta.parse。这几乎肯定是OP所要求的,但绝对不是他们应该要求的。使用通用解析器解析用户输入非常危险,即使在一次性情况下(因为这种代码往往超出预期)。请参见最近的log4j事件,以清楚地说明让这种事情进入代码库看似无害的例子。 - Ted Dunning

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