Wolfram mathematica 数学中的交叉子表

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

我有以下两个清单

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]]]
应该生成一个空列表。我错过了一些琐碎的事情吗?

这可能是你的想法吗

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好的,现在需要有人进行编辑,这样我才能逆转我的投票。