What is the best way to match list entries after rounding in Mathematica?

I have two lists in Mathematica:

list1 = {{a1, b1, c1}, ... , {an, bn, cn}} 

and

list2 = {{d1, e1, f1}, ... , {dn, en, fn}}

the lists contain numerical results and approximately consist of 50,000 triplets each. Each triplet represents two coordinates and a numerical value of some property in these coordinates. Each list has a different length, and the coordinates are not exactly the same. My intention is to match the numerical values ​​of the third property from each list, so I need to scan the lists and determine the properties whose coordinates are the same. My conclusion will be similar to

list3 = {{ci, fj}, ... , {cl, fm}}

Where

{ai, bi}, ..., {al, bl}

will be (approximately) equal, respectively

{dj, ej}, ..., {dm, em}

By “roughly” I mean that the coordinates will be rounded to the desired accuracy:

list1(2) = Round[{#[[1]], #[[2]], #[[3]]}, {1000, 500, 0.1}] & /@ list1(2)

, . , ?

6

list1 = {{-1.16371*10^6, 548315., 14903.}, {-1.16371*10^6, 548322., 14903.9}, 
   {-1.16371*10^6, 548330., 14904.2}, {-1.16371*10^6, 548337., 14904.8}, 
   {-1.16371*10^6, 548345., 14905.5}, {-1.16371*10^6, 548352., 14911.5}}
+5
2

- :

{Round[{#, #2}], #3} & @@@ Join[list1, list2];

% ~GatherBy~ First ~Select~ (Length@# > 1 &)

, . Round, .

, . , , . , , .

Sow Reap. . - , .

Reap[
  Sow[#3, {Round[{#, #2}]}] & @@@ Join[list1, list2],
  _,
  List
][[2]] ~Cases~ {_, {_, __}}

, Round GatherBy .

newList1 = GatherBy[{Round[{#, #2}], #3} & @@@ list1, First][[All, 1]];

newList2 = GatherBy[{Round[{#, #2}], #3} & @@@ list2, First][[All, 1]];

:

newList1 ~Join~ newList2 ~GatherBy~ First ~Select~ (Length@# > 1 &)
+5

, Nearest, .

, list1 , list2. ( {list1, list2} = {list2, list1})

(* extract points *)

points1=list1[[All,{1,2}]];
points2=list2[[All,{1,2}]];

(* build a "nearest-function" for matching them *)

nf=Nearest[points1]

(* two points match only if they're closer than threshold *)
threshold=100;

(* This function will find the match of a point from points2 in points1.  
   If there no match, the point is discarded using Sequence[]. *)
match[point_]:= 
   With[{m=First@nf[point]}, 
       If[Norm[m-point]<threshold, {m,point}, Unevaluated@Sequence[]]
   ]

(* find matching point-pairs *)
matches=match/@points1;

(* build hash tables to retrieve the properties associated with points quickly *)
Clear[values1,values2]
Set[values1[{#1,#2}],#3]&@@@list1;
Set[values2[{#1,#2}],#3]&@@@list2;

(* get the property-pairs *)
{values1[#1],values2[#2]}&@@@matches

DistanceFunction , values1 values2, . , .

. , . ? ? ? .. -, , , .

+4

All Articles