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 に対して 1 つの値のみを返します。ID2 のすべての値を取得するにはどうすればよいですか?

4

5 に答える 5

7

他のソリューションを補完するために、この問題のハイ パフォーマンス コーナー、つまり、テーブルが大きく、多くのクエリを実行する必要がある場合を調べたいと思います。明らかに、ある種の前処理は、そのような場合に多くの実行時間を節約できます。と の組み合わせに基づく、かなりあいまいですが IMO のエレガントなソリューションを示したいと思いDispatchます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、元のテーブルからルールの -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 で直接調べたい場合などです。

于 2011-08-03T22:42:23.523 に答える
4

すべての答えが、このような状況のためにほぼ具体的に意図された機能、つまりPickを見逃しているようです。Pick秒の対応する要素が True であるリストの要素を返します。3 番目の引数 (2 番目のリストの要素が一致するパターン) を持つ形式 (これを使用します) もあります。

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

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

于 2011-08-04T01:04:42.813 に答える