Wolfram mathematica Mathematica中四舍五入后匹配列表项的最佳方法是什么?

Wolfram mathematica Mathematica中四舍五入后匹配列表项的最佳方法是什么?,wolfram-mathematica,Wolfram Mathematica,我在Mathematica有两个列表: list1 = {{a1, b1, c1}, ... , {an, bn, cn}} 及 这些列表包含数字结果,大致由50000个三元组组成。每个三元组表示两个坐标和这些坐标处某个属性的数值。每个列表的长度不同,坐标范围也不尽相同。我的目的是关联每个列表中第三个属性的数值,因此我需要扫描列表并识别坐标匹配的属性。我的输出将类似于 list3 = {{ci, fj}, ... , {cl, fm}} 在哪里 {ai, bi}, ..., {al, bl

我在Mathematica有两个列表:

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

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

list3 = {{ci, fj}, ... , {cl, fm}}
在哪里

{ai, bi}, ..., {al, bl}
将(大致)分别等于

{dj, ej}, ..., {dm, em}
所谓“粗略”,我的意思是,一旦四舍五入到所需的精度,坐标将匹配:

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}}

您可能需要使用以下内容:

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

% ~GatherBy~ First ~Select~ (Length@# > 1 &)
这将对舍入后具有匹配坐标的所有数据点进行分组。您可以使用第二个参数对进行舍入以指定要舍入的分数

这假定单个列表中没有重复的点。如果有,您将需要删除这些以获得有用的对。如果是这样,请告诉我,我会更新我的答案

下面是另一种使用
Sow
eaw
的方法。同样的警告也适用。这两个示例都只是指导您如何实现功能的指南

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 &)

这是我的方法,依赖于匹配点

让我们假设
list1
的元素不少于
list2
。(否则,您可以使用
{list1,list2}={list2,list1}
交换它们)

(*提取点*)
points1=list1[[All,{1,2}]];
points2=list2[[All,{1,2}]];
(*构建一个“最近函数”以匹配它们*)
nf=最近的[点1]
(*两个点仅在接近阈值时匹配*)
阈值=100;
(*此函数将从点S1中的点S2查找点的匹配。
如果不匹配,则使用序列[].*)放弃该点
匹配[点]:=
与[{m=First@nf[点]},

如果[Norm[m-point]可以为
list1
list2
以及预期输出
list3
发布小数值示例吗?同样,定义“粗略”Wizard先生-是的,这看起来很有希望,但正如您所说,在四舍五入后,每个列表中可能有具有重复坐标的元素,在这种情况下,单个代表性元素就足够了。+1,对于最巧妙的(隐蔽的?)中缀形式的使用我见过。@gpap如果是这样,我们需要先过滤每个列表。我会修改我的答案。@rcollyer我希望这不难读。我最近决定开始用中缀符号发布代码,因为我会自己编写代码。乍一看有点混乱,特别是因为它不强调分组(
(#1~GatherBy#2)~Select#3
):D我通常只对关联函数使用中缀,例如
连接
(这意味着所有参数的类型都相同)。
newList1 ~Join~ newList2 ~GatherBy~ First ~Select~ (Length@# > 1 &)
(* 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's 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