Wolfram mathematica 数学中的交叉子表
我有以下两个清单 l1 = {{{2011, 3, 13}, 1}, {{2011, 3, 14}, 1}, {{2011, 3, 15}, 1}, {{2011, 3, 16}, 2}, {{2011, 3, 17}, 3}}; l2 = {{{2011, 3, 13}, 40}, {{2011, 3, 16}, 50}, {{2011, 3, 17}, 60}}; l1={{{2011,3,13},1},{{2011,3,14},1},{2011,3,15}, 1}, {{2011, 3, 16}, 2}, {{2011, 3, 17}, 3}}; l2={{2011,3,13,40},{{2011,3,16,50},{2011,3,17,60}; 我需要从l2中提取日期(每个l2元素的第一个元素)与l1中日期匹配的项目(以便生成两个长度完全相同的列表) 我不明白为什么会这样: Select[l1, MemberQ[Transpose[l2][[1]], #[[1]]]] 选择[l1,MemberQ[转置[l2][[1]],#[[1]]]Wolfram mathematica 数学中的交叉子表,wolfram-mathematica,transpose,Wolfram Mathematica,Transpose,我有以下两个清单 l1 = {{{2011, 3, 13}, 1}, {{2011, 3, 14}, 1}, {{2011, 3, 15}, 1}, {{2011, 3, 16}, 2}, {{2011, 3, 17}, 3}}; l2 = {{{2011, 3, 13}, 40}, {{2011, 3, 16}, 50}, {{2011, 3, 17}, 60}}; l1={{{2011,3,13},1},{{2011,3,14},1},{2011,3,15}, 1}, {{2011
应该生成一个空列表。我错过了一些琐碎的事情吗?这可能是你的想法吗
dates=Transpose[l2][[1]];
Cases[l1, {x_, _} /; MemberQ[dates, x]]
你忘了带符号。应该是
Select[l1, MemberQ[Transpose[l2][[1]], #[[1]]]&]
Sjoerd向您展示了如何使您的方法工作,但它不是最佳的。问题是,
Transpose[l2][[1]]
会针对l1
中的每个元素再次求值。David给出了一种只执行该步骤一次的方法。您还可以使用:
Cases[l1, {Alternatives @@ l2[[All, 1]], _}]
这是我的非排序交叉点代码:
NonSortingIntersection[l1_, l2_, test_: SameQ] :=
Module[{res =
Last@Reap[
Scan[Extract[l1,
Position[l1, x_ /; test[x, #], {1}, 1, Heads -> False],
Sow] &, l2]]}, If[res === {}, res, First[res]]]
用法如下:
In[22]:= NonSortingIntersection[l1, l2,
Function[{x, y}, First[x] == First[y]]]
Out[22]= {{{2011, 3, 13}, 1}, {{2011, 3, 16}, 2}, {{2011, 3, 17}, 3}}
请注意,与其他解决方案不同,输出的长度保证不再是l2
的长度。例如:
In[24]:= Cases[Join[l1, l1], {x_, _} /; MemberQ[Evaluate[Transpose[l2][[1]]], x]]
Out[24]= {{{2011, 3, 13}, 1}, {{2011, 3, 16}, 2}, {{2011, 3, 17},
3}, {{2011, 3, 13}, 1}, {{2011, 3, 16}, 2}, {{2011, 3, 17}, 3}}
In[25]:= NonSortingIntersection[Join[l1, l1], l2,
Function[{x, y}, First[x] == First[y]]]
Out[25]= {{{2011, 3, 13}, 1}, {{2011, 3, 16}, 2}, {{2011, 3, 17}, 3}}
这可能是可取的,也可能不是可取的,但这取决于radhat谁更了解他的问题。当列表变大时,一种更快的方法:
DeleteCases[GatherBy[Join[l1, l2], First], {_}][[All, 1]]
(* Out= {{{2011, 3, 13}, 40}, {{2011, 3, 16}, 50}, {{2011, 3, 17}, 60}} *)
如果列表可能包含重复项,则可以使用
l1=GatherBy[l1,First][[All,1]]
首先删除重复项 您好,大卫,就是这样(实际上有一个小改动:第一行应该是l2),谢谢您的及时回复!我仍然困惑于为什么我的方法不起作用though@David请注意,此解决方案还计算x的每个元素的转置。这可以通过评估
案例[l1,{x_u,}/;MemberQ[Print[1];Transpose[l2][[1]],x]
来看出。执行时会打印5个数字。Sasha是对的,如果这是你的意图,你的新表格与之前的表格不同。你需要一个Evaluate
在那里:Cases[l1,{x_u,}/;MemberQ[Evaluate[Transpose[l2][[1]]],x]
@Sasha MemberQ似乎要分别检查l1中的每个元素。@David但是你应该在Evaluate
中包含Print
。然后对MemberQ的参数求值,然后结果模式将用于l1
的每个元素。这样,您将对转置进行一次评估。否则条件
,即/
保存其参数,MemberQ
及其参数只有在pattern matcher找到x
后才会进行计算,并且每次匹配都会重复此计算,即对于l1
的每个元素,尽管我的回答是正确的,而且是第一个,但Sjoerd发现了代码中的问题(缺少的符号和)在我看来,这样就更好地回答了你的问题。所以请随意改变你的选择。拉德拉特,我同意大卫的观点。Sjoerd是回答你实际问题的人,我觉得它值得你接受。我发布了我觉得最干净的方法,我希望它能有所帮助,但是像大卫和我这样的回复是对这件事的辅助。+1真的很好。我第一次看到备选方案的应用
“我喜欢这样。您可能会意识到这一点,但这会对l1
的每个元素计算转置[l2][[1]]
。最好使用Select[l1,MemberQ[Evaluate[Transpose[l2][[1]]],#[[1]]]&
@Sash-Yep,这似乎是问题的唯一答案。请注意,OP没有要求提供替代方案,只是解释他自己的方法不起作用的原因。这不会产生相同的结果。我更改了零件规格以匹配。感谢您捕捉到@TomD。@TomD很抱歉,我没有看到任何声明,说明列表的第一个元素中没有重复项,无论是在问题中还是在这个答案中。否则,这就不是一个解决方案。考虑:l1={{1,a},{2,b},{3,c},{4,d},{2,x};l2={1,“q”},{3,“r”}代码>或:l1={{1,“a”},{2,“b”},{3,“c”},{4,“d”};l2={5,“q”},{5,“r”},{2,“s”}代码>--在我看来,两者都没有给出正确的结果。@L2先生是一个日期列表,不可能包含重复的日期。如果是这样,所有解决方案都会失败,因为它们不会“生成两个长度完全相同的列表”。如果L1包含重复项,并且这是一个问题,则可以轻松删除它们?。伊姆霍,约书亚的方法很好,说明了GatherBy的用法,并且适用于OP给出的示例。@TomD好的,现在需要有人进行编辑,这样我才能逆转我的投票。