打印与表中的重复输入相对应的不同输出值?

时间:2011-08-03 21:40:35

标签: duplicates wolfram-mathematica string-search

例如,TableA

     ID1    ID2   
     123    abc
     123    def
     123    ghi
     123    jkl
     123    mno
     456    abc
     456    jkl

我想对123进行字符串搜索并返回所有相应的值。

    pp = Cases[#, x_List /; 
     MemberQ[x, y_String /; 
       StringMatchQ[y, ToString@p, IgnoreCase -> True]], {1}] &@TableA

    {f4@"ID2", f4@pp[[2]]}

上面,p是输入,或123.这只返回ID2的一个值。如何获取ID2的所有值?

5 个答案:

答案 0 :(得分:7)

为了补充其他解决方案,我想探索这个问题的高性能角落,即表格很大的情况,并且需要执行许多查询。显然,在这种情况下,某种预处理可以节省大量的执行时间。我想基于DispatchReplaceList的组合展示一个相当模糊但IMO优雅的解决方案。这是一个用于说明的小表(我使用所有条目的字符串,以使其接近原始问题):

makeTestTable[nids_, nelems_] :=
  Flatten[Thread[{"ID" <> ToString@#, 
         ToString /@ Range[#, nelems + # - 1]}] & /@ Range[nids], 1]

In[57]:= (smallTable = makeTestTable[3,5])//InputForm
Out[57]//InputForm=
{{"ID1", "1"}, {"ID1", "2"}, {"ID1", "3"}, {"ID1", "4"}, {"ID1", "5"}, 
 {"ID2", "2"}, {"ID2", "3"}, {"ID2", "4"}, {"ID2", "5"}, {"ID2", "6"}, 
 {"ID3", "3"}, {"ID3", "4"}, {"ID3", "5"}, {"ID3", "6"}, {"ID3", "7"}}

预处理步骤包括从原始表格中制作Dispatch - ed规则表:

smallRules = Dispatch[Rule @@@ smallTable];

获取(例如,“ID2”)值的代码是:

In[59]:= ReplaceList["ID2", smallRules]

Out[59]= {"2", "3", "4", "5", "6"}

这看起来不是什么大问题,但让我们转向更大的表格:

In[60]:= Length[table = makeTestTable[1000,1000]]
Out[60]= 1000000

预处理步骤无疑需要一些时间:

In[61]:= (rules = Dispatch[Rule @@@ table]); // Timing

Out[61]= {3.703, Null}

但我们只需要一次。现在,所有后续查询(可能除了第一个)都将近乎即时:

In[75]:= ReplaceList["ID520",rules]//Short//Timing
Out[75]= {0.,{520,521,522,523,524,525,<<988>>,1514,1515,1516,1517,1518,1519}}

虽然没有预处理的方法对于此表大小需要相当大的时间:

In[76]:= Cases[table,{"ID520",_}][[All,2]]//Short//Timing
Out[76]= {0.188,{520,521,522,523,524,525,<<988>>,1514,1515,1516,1517,1518,1519}}

我意识到这可能对原始问题来说太过分了,但是这样的任务很常见,例如当有人想要直接在Mathematica中探索从数据库导入的大型数据集时。

答案 1 :(得分:4)

似乎所有的答案都错过了几乎专门针对这种情况的功能,即PickPick返回列表中的元素,其中第二个对应的元素为True。甚至有一种格式(我将使用)有第三个参数,第二个列表的元素应匹配的模式。

list1 = {"ID1", "123", "123", "123", "123", "123", "456", "456"};
list2 = {"ID2", "abc", "def", "ghi", "jkl", "mno", "abc", "jkl"};

Pick[list2, list1, "123"]

==> {"abc", "def", "ghi", "jkl", "mno"}

答案 2 :(得分:3)

lis = {{"ID1", "ID2"},
  {"123", "abc"},
  {"123", "def"},
  {"123", "ghi"},
  {"123", "jkl"},
  {"123", "mno"},
  {"456", "abc"},
  {"456", "jkl"}}

(result = Cases[lis, {x_, y_} /; StringMatchQ[x, "123"] :> {x,y}]) // TableForm

enter image description here

如果只想要RHS,那么

Cases[lis, {x_, y_} /; StringMatchQ[x, "123"] :> y] // TableForm

enter image description here

答案 3 :(得分:2)

此?

Last@Transpose[Cases[tableA, {ToString@p, _}]]

(因为我不能只根据你的问题剪切和粘贴tableA格式化的方式,我没有尝试过。

答案 4 :(得分:1)

TableA [[#[[1]],2]]&amp; / @ Position [TableA,123]