gpt4 book ai didi

dataframe - 在 Julia 中用另一个 DF 替换 DF 中的列

转载 作者:行者123 更新时间:2023-12-02 18:08:02 25 4
gpt4 key购买 nike

假设我有两个 DataFrame df1df2 如下

df1 = DataFrame(id=["a", "a", "a", "b", "b", "b", "c", "c", "c", "d", "d"],
var=[1, 32, 3, 22, 5, 4, 6, 7, 8, 4, 3])

11×2 DataFrame
Row │ id var
│ String Int64
─────┼───────────────
1 │ a 1
2 │ a 32
3 │ a 3
4 │ b 22
5 │ b 5
6 │ b 4
7 │ c 6
8 │ c 7
9 │ c 8
10 │ d 4
11 │ d 3

df2 = DataFrame(id=["a", "a", "b", "b", "b", "c", "c", "c"],
var=[1, 1, 2, 2, 2, 6, 6, 6])

8×2 DataFrame
Row │ id var
│ String Int64
─────┼───────────────
1 │ a 1
2 │ a 1
3 │ b 2
4 │ b 2
5 │ b 2
6 │ c 6
7 │ c 6
8 │ c 6

目标是将每个 id 的 df1 中的 var 列替换为 df2 中的 var 值> 对于每个相应的 id,仅适用于 df2df1 中同时存在的那些 id

所以期望的结果将如下所示:

DataFrame(id=["a", "a", "a", "b", "b", "b", "c", "c", "c", "d", "d"],
var=[1, 32, 3, 22, 5, 4, 6, 7, 8, 4, 3])

11×2 DataFrame
Row │ id var
│ String Int64
─────┼───────────────
1 │ a 1
2 │ a 1
3 │ a 1
4 │ b 2
5 │ b 2
6 │ b 2
7 │ c 6
8 │ c 6
9 │ c 6
10 │ d 4
11 │ d 3

尝试了以下方法,但不起作用

for d1 in groupby(df1, :id)
replace!(d1.var .= [d2.var for d1 in groupby(df2, :id)])
end

#or

[[d1.var = d2.var for d2 in groupby(df2, :id)] for d1 in groupby(df1, :id)]

将不胜感激任何帮助。谢谢!

最佳答案

我会这样做:

julia> leftjoin!(df1, unique(df2, :id), on=:id, makeunique=true)
11×3 DataFrame
Row │ id var var_1
│ String Int64 Int64?
─────┼────────────────────────
1 │ a 1 1
2 │ a 32 1
3 │ a 3 1
4 │ b 22 2
5 │ b 5 2
6 │ b 4 2
7 │ c 6 6
8 │ c 7 6
9 │ c 8 6
10 │ d 4 missing
11 │ d 3 missing

julia> select!(df1, :id, [:var_1, :var] => ByRow(coalesce) => :var)
11×2 DataFrame
Row │ id var
│ String Int64
─────┼───────────────
1 │ a 1
2 │ a 1
3 │ a 1
4 │ b 2
5 │ b 2
6 │ b 2
7 │ c 6
8 │ c 6
9 │ c 6
10 │ d 4
11 │ d 3

请注意,您的数据的问题是 df2 对于相同的唯一 :id 有多个行,因此我之前对其运行 unique加入(另请注意,df1df2 中每组的值数量不同)。

还有其他方法可以做到这一点(如果您想查看它们,请发表评论),但它们会涉及更多代码(通过组迭代等)。我提出的解决方案依赖于 DataFrames.jl API 的功能。

编辑

性能比较(首次运行包括编译时间):

julia> repeat!(df1, 10^6);

julia> function sol1(df1, df2)
leftjoin!(df1, unique(df2, :id), on=:id, makeunique=true)
select!(df1, :id, [:var_1, :var] => ByRow(coalesce) => :var)
end
sol1 (generic function with 1 method)

julia> function sol2(df1, df2)
D = Dict(df2[!, :id] .=> df2[!, :var])
for (i, v) in enumerate(df1[!, :id])
if v in keys(D)
df1[!, :var][i] = D[v]
end
end
end
sol2 (generic function with 1 method)

julia> function sol3(var1, var2, id1, id2)
D = Dict(id2 .=> var2)
for (i, v) in enumerate(id1)
if v in keys(D)
var = D[v]
end
end
end
sol3 (generic function with 3 methods)

julia> x = copy(df1);

julia> @time sol1(x, df2);
3.103564 seconds (4.97 M allocations: 685.190 MiB, 4.84% gc time, 80.37% compilation time)

julia> x = copy(df1);

julia> @time sol1(x, df2);
0.660479 seconds (585 allocations: 409.727 MiB, 23.24% gc time)

julia> x = copy(df1);

julia> @time sol2(x, df2);
3.462888 seconds (55.36 M allocations: 1.495 GiB, 6.22% gc time, 3.58% compilation time)

julia> x = copy(df1);

julia> @time sol2(x, df2);
3.382529 seconds (55.00 M allocations: 1.475 GiB, 7.24% gc time)

julia> x = copy(df1);

julia> @time sol3(x.var, df2.var, x.id, df2.id);
0.380297 seconds (142.77 k allocations: 7.360 MiB, 9.58% compilation time)

julia> x = copy(df1);

julia> @time sol3(x.var, df2.var, x.id, df2.id);
0.331760 seconds (5 allocations: 720 bytes)

关于dataframe - 在 Julia 中用另一个 DF 替换 DF 中的列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72864330/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com