Birkaç dizini eşleştirme
Farklı testlerde ve çeşitli koşullar altında birkaç numuneyi karşılaştırmam gereken geniş bir veri kümesine sahibim. Bunları kolayca eşleştirmenin ve analiz etmenin bir yolunu arıyorum. Örnek olarak, (C) x, y ve z koşulları altında (T) 1 ve 2 testlerinden geçen ve (R) R1 ve R2 sonuçlarını veren Örnek (S) a, b ve c'ye sahip olduğumu varsayalım.
S T C R1 R2
a 1 x 2.9
a 1 y 2.6
a 1 z 8.7
a 2 x 9.4 0.372
a 2 y 8.1 0.208
a 2 z 7.6 0.154
b 1 x 7.5
b 1 y 7.3
b 1 z 1.7
b 2 x 3.9 0.213
b 2 y 7.9 0.435
b 2 z 2.5 0.294
c 1 x 6.2
c 1 y 1.8
c 1 z 6.3
c 2 x 1.5 0.246
c 2 y 6.0 0.496
c 2 z 1.7 0.167
Testlerin farklı çıktıları var ve teste bağlı olarak belirli işlevleri uygulamam gerekiyor. Gibi:
Test1[a,b] = R1a/R1b
Test2[a,b] = R1a/R2a - R1b/R2b
Testler yalnızca eşleşen koşullara sahip numunelere uygulanmalıdır, ancak her numune eşleştirilmelidir. Sonuç şöyle olur:
S1 S2 T C R
a b 1 x 2.9/7.5
a c 1 x 2.9/6.2
a b 2 x 9.4/0.372-3.9/0.213
a c 2 x 9.4/0.372-1.5/0.246
a b 1 y 2.6/7.3
...
Bir süredir bunu düzeltmeye çalışıyorum ve sonunda kendimi karıştırıyorum. Bir çözümü veya önerisi olan var mı? Örneğin kolayca kopyalanabilen bir biçimini istiyorsanız:
{{S, T, C, R1, R2}, {a, 1, x, 2.9}, {a, 1, y, 2.6}, {a, 1, z, 8.7},
{a, 2, x, 9.4, 0.372}, {a, 2, y, 8.1, 0.208}, {a, 2, z, 7.6, 0.154},
{b, 1, x, 7.5}, {b, 1, y, 7.3}, {b, 1, z, 1.7}, {b, 2, x, 3.9, 0.213},
{b, 2, y, 7.9, 0.435}, {b, 2, z, 2.5, 0.294}, {c, 1, x, 6.2}, {c, 1, y, 1.8},
{c, 1, z, 6.3}, {c, 2, x, 1.5, 0.246}, {c, 2, y, 6., 0.496}, {c, 2, z, 1.7, 0.167}}
Yanıtlar
Hangi sonuçların yeniden birleştirilmesi gerektiğini doğru anladığımdan emin değilim, ancak bu kod şunları yapar: Önce veriler koşullara göre toplanır, sonra testle, ardından uzunluk 2'nin alt kümeleri oluşturulur ve son adımda sonuçların sayısal hesaplaması uygulandı:
test1[{{a_,1,c_,R1a_},{b_,1,c_,R1b_}}]:={a,b,1,c,R1a/R1b}
test2[{{a_,2,c_,R1a_,R2a_},{b_,2,c_,R1b_,R2b_}}]:={a,b,2,c,R1a/R2a-R1b/R2b}
{{S,T,C,R1,R2},{a,1,x,2.9},{a,1,y,2.6},{a,1,z,8.7},{a,2,x,9.4,0.372},{a,2,y,8.1,0.208},{a,2,z,7.6,0.154},{b,1,x,7.5},{b,1,y,7.3},{b,1,z,1.7},{b,2,x,3.9,0.213},{b,2,y,7.9,0.435},{b,2,z,2.5,0.294},{c,1,x,6.2},{c,1,y,1.8},{c,1,z,6.3},{c,2,x,1.5,0.246},{c,2,y,6.,0.496},{c,2,z,1.7,0.167}};
GatherBy[%,#[[3]]&][[2;;]];
Flatten[GatherBy[#,{x}\[Function]x[[2]]]&/@%,1];
Flatten[Subsets[#,{2}]&/@%,1];
If[#[[1,2]]===1,test1[#],test2[#]]&/@%;
%//TableForm
hangi sonuçlanır
a b 1 x 0.386667
a c 1 x 0.467742
b c 1 x 1.20968
a b 2 x 6.95896
a c 2 x 19.1713
b c 2 x 12.2123
a b 1 y 0.356164
a c 1 y 1.44444
b c 1 y 4.05556
a b 2 y 20.7814
a c 2 y 26.8455
b c 2 y 6.06415
a b 1 z 5.11765
a c 1 z 1.38095
b c 1 z 0.269841
a b 2 z 40.8472
a c 2 z 39.171
b c 2 z -1.67624
Belirli bir test ve koşul için tüm olası alt kümeleri içerdiği için bu OP beklenen sonuç değildir (örneğin, x koşulu altında üçüncü giriş b, c testi 1). Sonuçların kombinasyonu için daha kapsamlı bir kriter varsa, yukarıdaki kodda alt grupları oluşturan adımın değiştirilmesi / rafine edilmesi gerekir. SubsequencesBunun yerine kullanmak , Subsetsyalnızca OP'nin aradığı çözüm olabilecek sıralı demetleri dikkate alır:
a b 1 x 0.386667
b c 1 x 1.20968
a b 2 x 6.95896
b c 2 x 12.2123
a b 1 y 0.356164
b c 1 y 4.05556
a b 2 y 20.7814
b c 2 y 6.06415
a b 1 z 5.11765
b c 1 z 0.269841
a b 2 z 40.8472
b c 2 z -1.67624
data = {{"S", "T", "C", "R1", "R2"}, {a, 1, x, 2.9}, {a, 1, y,
2.6}, {a, 1, z, 8.7}, {a, 2, x, 9.4, 0.372}, {a, 2, y, 8.1,
0.208}, {a, 2, z, 7.6, 0.154}, {b, 1, x, 7.5}, {b, 1, y, 7.3}, {b,
1, z, 1.7}, {b, 2, x, 3.9, 0.213}, {b, 2, y, 7.9, 0.435}, {b, 2,
z, 2.5, 0.294}, {c, 1, x, 6.2}, {c, 1, y, 1.8}, {c, 1, z,
6.3}, {c, 2, x, 1.5, 0.246}, {c, 2, y, 6., 0.496}, {c, 2, z, 1.7,
0.167}};
Grid[data, Dividers -> All, Background -> {None, 1 -> LightBlue},
Alignment -> {{Center, Center, Center, ".", "."}, Center}]
t1 = {#[[1]], #2[[1]], #[[2]], #[[3]], #[[4]]/#2[[4]]} &;
t2 = {#[[1]], #2[[1]], #[[2]], #[[3]], #[[4]]/#[[5]] - #2[[4]]/#2[[5]]} &;
proc = If[#[[1, 2]] === 1, t1 @@ #, t2 @@ #] &;
GroupByverileri {test, condition}(sütun 2 ve 3) ve aşağıdakileri kullanarak 2 alt kümeleri işleyin proc:
data2 = Join @@ Values @ GroupBy[Rest @ data, #[[{2, 3}]] &,
Map[proc] @ Subsets[#, {2}] &];
Grid[Prepend[{"S1", "S2", "T", "C", "R"}]@data2,
Dividers -> All, Background -> {None, 1 -> LightBlue},
Alignment -> {{Center, Center, Center, Center, "."}, Center}]
Alternatif olarak şunları kullanabiliriz GatherBy:
data2 == Join @@ Map[Map[proc] @ Subsets[#, {2}]&] @ GatherBy[Rest@data, #[[{2, 3}]]&]
True