在Mathematica中舍入后匹配列表条目的最佳方法是什么?

gpa*_*pap 5 wolfram-mathematica

我在Mathematica中有两个列表:

list1 = {{a1, b1, c1}, ... , {an, bn, cn}} 
Run Code Online (Sandbox Code Playgroud)

list2 = {{d1, e1, f1}, ... , {dn, en, fn}}
Run Code Online (Sandbox Code Playgroud)

这些列表包含数字结果,大致由50000个三元组组成.每个三元组表示两个坐标和这些坐标处的某些属性的数值.每个列表具有不同的长度,并且坐标的范围不完全相同.我的目的是关联每个列表中第三个属性的数值,因此我需要扫描列表并识别坐标匹配的属性.我的输出将是这样的

list3 = {{ci, fj}, ... , {cl, fm}}
Run Code Online (Sandbox Code Playgroud)

哪里

{ai, bi}, ..., {al, bl}
Run Code Online (Sandbox Code Playgroud)

将(大致)分别等于

{dj, ej}, ..., {dm, em}
Run Code Online (Sandbox Code Playgroud)

通过"粗略",我的意思是坐标将匹配一次圆形到一些所需的精度:

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

所以在这个过程之后,我有两个列表,其中包含一些匹配的坐标.我的问题是如何执行识别它们的操作并以最佳方式挑选出属性对?

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}}
Run Code Online (Sandbox Code Playgroud)

Mr.*_*ard 5

你可能想要使用这样的东西:

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

% ~GatherBy~ First ~Select~ (Length@# > 1 &)
Run Code Online (Sandbox Code Playgroud)

这将在舍入后对具有匹配坐标的所有数据点进行分组.您可以使用第二个参数来Round指定要舍入的分数.

这假设单个列表中没有重复的点.如果有,您将需要删除它们以获得有用的对.告诉我,如果是这种情况,我会更新我的答案.

这是使用Sow和的另一种方法Reap.同样的警告适用.这两个示例都是您实现功能的指南.

Reap[
  Sow[#3, {Round[{#, #2}]}] & @@@ Join[list1, list2],
  _,
  List
][[2]] ~Cases~ {_, {_, __}}
Run Code Online (Sandbox Code Playgroud)

要处理每个列表中的重复后续元素,您可以按如下方式在每个列表中使用RoundGatherBy.

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

newList2 = GatherBy[{Round[{#, #2}], #3} & @@@ list2, First][[All, 1]];
Run Code Online (Sandbox Code Playgroud)

然后继续:

newList1 ~Join~ newList2 ~GatherBy~ First ~Select~ (Length@# > 1 &)
Run Code Online (Sandbox Code Playgroud)