这个问题是前一个线程的延续,用于比较具有相同长度的两个列表:
Is there any efficient easy way to compare two lists with the same length with Mathematica?
鉴于两个列表A={a1,a2,a3,...an}
和B={b1,b2,b3,...bn}
,我会说A>=B
当且仅当所有ai>=bi
。现在我们有k
个列表H={{a11,a12,a13,...a1n}, {a21,a22,a23,...a2n},...,{ak1,ak2,ak3,...akn}}
,并希望找到最大值(如果存在)。
这是我的代码:
Do[If[NonNegative[Min[H[[i]] - h]], h = H[[i]], ## &[]], {i, h = H[[1]]; 1, Length[H]}];h
这样做的更好的伎俩是什么?
编辑:
我想将其定义为以下函数:
maxList[H_]:=Do[If[NonNegative[Min[H[[i]] - h]], h = H[[i]], ## &[]], {i, h = H[[1]]; 1, Length[H]}];h
但问题是上面的代码跨越两行,对此有什么解决方法吗?这里有一些代码工作,但不是那么漂亮
maxList[H_] := Module[{h = H[[1]]}, Do[If[NonNegative[Min[H[[i]] - h]], h = H[[i]], ## &[]], {i, Length[H]}]; h]
或
maxList[H_]:=Last[Table[If[NonNegative[Min[H[[i]] - h]], h = H[[i]], ## &[]], {i, h = H[[1]]; 1, Length[H]}]]
答案 0 :(得分:5)
在我看来,这应该有效:
maxList = # \[Intersection] {Max /@ Transpose@#} &;
maxList[ {{4, 5, 6}, {1, 4, 3}, {4, 3, 5}, {5, 6, 7}} ]
{{5, 6, 7}}
我没有考虑使用Intersection
的费用,Artes表示MemberQ
是更好的选择。 (请像我一样投票给他答案)。我会在不使用Module
的情况下编写函数:
maxList[a_] := If[MemberQ[a, #], #, {}] &[Max /@ Transpose@a]
快速的方法几乎等同于完全:
maxList = Cases[#, Max /@ Transpose@# , 1, 1] &;
结果采用{{a, b, c}}
或{}
形式,而不是{a, b, c}
或{}
。
答案 1 :(得分:3)
Mr.Wizard的方法的修改速度提高了几倍。
maxListFast[list_List] := Module[{l},
l = Max /@ Transpose@list;
If[MemberQ[list, l], l, {}]]
我们用
测试这两种方法test = RandomInteger[100, {500000, 10}];
test1 = Insert[test, Table[100, {10}], RandomInteger[{1, 500000}]];
我们得到了
In[5]:= maxList[test] // Timing
maxListFast[test] // Timing
Out[5]= {2.761, {}}
Out[6]= {0.265, {}}
和
In[7]:= maxList[test1] // Timing
maxListFast[test1] // Timing
Out[7]= {1.217, {{100, 100, 100, 100, 100, 100, 100, 100, 100, 100}}}
Out[8]= {0.14, {100, 100, 100, 100, 100, 100, 100, 100, 100, 100}}
修改强>
一般来说,要选择一种方法,我们首先应该知道我们要处理哪种数据。 (列表的长度,数量,数字类型)。虽然我们有大量的短名单
整数maxListFast
的效果甚至比maxList
好10倍(如果长度为10的500000个列表)。
然而,对于实数列表,它仅快3-4倍,并且我们拥有的列表越多越长,它越慢,例如, :
A = RandomReal[1000, {3000, 3000}];
First@AbsoluteTiming[maxListFast@A;]/ First@AbsoluteTiming[maxList@A;]
Out[19]= 2.040516
但是如果我们插入“最大元素”:
In[21]:= IA = Insert[A, Table[1000, {3000}], RandomInteger[{1, 3000}]];
In[22]:= First@AbsoluteTiming[maxListFast@IA;]/ First@AbsoluteTiming[maxList@IA;]
Out[22]= 0.9781931
时间关闭。
答案 2 :(得分:2)
一些数据:顺便说一下,实际上并不需要标记各个子列表。我这样做是为了方便参考。
a = {4, 5, 6}; b = {1, 4, 3}; c = {4, 3, 5}; d = {5, 6, 7};
lists = {a, b, c, d};
maxList 确定子列表是否是最大列表,即其每个元素是否大于所有其他子列表中的相应元素。我们最初假设子列表是最大列表。如果违反了该假设(注意使用Negative
而不是NonNegative
)则返回False。顺便说一句,列表将与自身进行比较;这比从lists
删除它更容易;它不会影响结果。
maxList[list_] :=
Module[{result = True, n = 1},
While[n < Length[lists] + 1,
If[Negative[Min[list - lists[[n]]]], result = False; Break[]]; n++]; result]
现在让我们检查上面的一个子列表是否是maxList:
greatestList = {};
n = 1; While[n < Length[lists] + 1,
If[maxList[lists[[n]]], greatestList = lists[[n]]; Break[]]; n++];
Print["The greatest list (if one exists): ", greatestList]
(* output *)
The greatest list (if one exists): {5,6,7}
子列表d是maxList。
如果没有maxList,结果将是空列表。