回答編集履歴

1

2022/11/10 17:25

投稿

melian
melian

スコア19825

test CHANGED
@@ -1,6 +1,18 @@
1
- 効率的かどうかは不明。
1
+ ※ Benchmark
2
2
  ```julia
3
- using(DataFrames)
3
+ using DataFrames
4
+ using BenchmarkTools
5
+
6
+ function replace_by_ifelse(dfA, dfB)
7
+ dfA.D = ifelse.((dfA.A .== dfB.A) .& (dfA.B .== dfB.B), dfB.C, "X")
8
+ return dfA
9
+ end
10
+
11
+ function replace_by_transform(dfA, dfB)
12
+ transform!(hcat(dfA, dfB, makeunique=true), [:A, :B, :A_1, :B_1, :C_1]
13
+ => ByRow((a1, b1, a2, b2, c) -> (a1 == a2) & (b1 == b2) ? c : "X")
14
+ => :D)[!, append!(names(dfA), ["D"])]
15
+ end
4
16
 
5
17
  data_frame = DataFrame(
6
18
  A = [1, 1, 1, 1, 2, 2, 2, 2],
@@ -14,21 +26,15 @@
14
26
  C = ["A", "B", "C", "D", "A", "B", "C", "D"]
15
27
  )
16
28
 
17
- idx = (data_frame.A .== match_frame.A) .& (data_frame.B .== match_frame.B)
18
- data_frame.D = ifelse.(idx, match_frame.C, "X")
29
+ @btime replace_by_ifelse(data_frame, match_frame)
30
+ # => 1.788 μs (10 allocations: 480 bytes)
19
31
 
20
- print(data_frame)
32
+ data_frame = DataFrame(
33
+ A = [1, 1, 1, 1, 2, 2, 2, 2],
34
+ B = [0, 1, 1, 0, 0, 0, 0, 1],
35
+ C = rand(8)
36
+ )
21
37
 
22
- # 8×4 DataFrame
23
- # Row │ A B C D
38
+ @btime replace_by_transform(data_frame, match_frame)
24
- # │ Int64 Int64 Float64 String
39
+ # => 119.151 μs (496 allocations: 36.24 KiB)
25
- # ─────┼────────────────────────────────
26
- # 1 │ 1 0 0.077777 X
27
- # 2 │ 1 1 0.162615 X
28
- # 3 │ 1 1 0.292393 C
29
- # 4 │ 1 0 0.677681 D
30
- # 5 │ 2 0 0.389061 X
31
- # 6 │ 2 0 0.23657 X
32
- # 7 │ 2 0 0.753411 X
33
- # 8 │ 2 1 0.402576 D
34
40
  ```