【问题标题】:Print Different Output Values Corresponding to Duplicate Input in a Table?打印对应于表中重复输入的不同输出值?
【发布时间】:2011-08-03 21:40:34
【问题描述】:

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

【问题讨论】:

    标签: duplicates wolfram-mathematica string-search


    【解决方案1】:

    为了补充其他解决方案,我想探索一下这个问题的高性能角落,即表很大并且需要执行许多查询的情况。显然,在这种情况下,某种预处理可以节省大量的执行时间。我想展示一个基于Dispatch 和ReplaceList 组合的相当晦涩但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
    • @Mr.Wizard 对我来说,有趣的是,Dispatch 对规则进行哈希处理,因此只有第一个具有相同 l.h.s 的规则。火灾(或者至少,这是我的想法),它仍然可以与ReplaceList 一起正常工作,它会尝试列表中的所有规则,并且不会影响性能。我之所以称它为晦涩难懂,是因为ReplaceList 和Dispatch 通常都不太常用,这里我们将它们组合在一起。
    • 也许我低估了复杂性。我没有受过计算机科学教育,因此我通常不会考虑某些东西 (Dispatch) 是如何工作的,而只是考虑它显然是如何工作的。我没有真正详细考虑过Dispatch 的工作原理,只是它显然优化了规则列表。您是否期望Dispatch 会在内部消除规则二和三:Dispatch @ {1 -&gt; x, 1 -&gt; y, 1 -&gt; z}?
    • @Mr.Wizard 是的,我认为这可能是一种情况。我不确切地知道Dispatch 是如何实现的,但文档是这样说的:“......诸如a[1]-&gt;a1 和a[2]-&gt;a2 之类的规则不能同时应用,不需要同时明确扫描。@987654342 @ 生成一个调度表,该表使用哈希码来指定哪些规则集实际上需要扫描特定的输入表达式。..."。因为我以前从未在工作中看到ReplaceList 和Dispatch 的组合,所以我不确定。顺便说一句,我也没有受过 CS 教育,这是我目前非常想念的东西。
    【解决方案2】:

    似乎所有答案都错过了几乎专门针对这种情况的功能,即Pick。 Pick返回列表中那些在一秒钟内对应的元素为 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"}
    

    【讨论】:

      【解决方案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
      

      【讨论】:

      • 您可以将表达式简化为Cases[lis, {"123", _}]和Cases[lis, {"123", v_} :&gt; v]。
      【解决方案4】:

      这个?

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

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-11
          • 2013-10-04
          • 2012-08-15
          • 2021-12-21
          • 1970-01-01
          相关资源
          最近更新 更多