4

例如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 的所有值?

4

5 回答 5

7

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

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从原始表制作一个规则表:

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 中探索从数据库导入的一些大型数据集时。

于 2011-08-03T22:42:23.523 回答
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"}
于 2011-08-04T09:41:16.763 回答
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

在此处输入图像描述

如果只想要RHS,那么

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

在此处输入图像描述

于 2011-08-03T22:22:15.620 回答
2

这?

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

(因为我不能只是tableA从你的问题中剪切和粘贴它的格式,所以我没有尝试过)。

于 2011-08-03T21:54:10.057 回答
1

表A[[#[[1]], 2]] & /@ 位置[表A, 123]

于 2011-08-04T01:04:42.813 回答