Вывести разные выходные значения, соответствующие повторяющимся данным в таблице? - PullRequest
4 голосов
/ 04 августа 2011

Например, 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 ]

7 голосов
/ 04 августа 2011

В дополнение к другим решениям я хотел бы исследовать высокопроизводительный угол этой проблемы, то есть случай, когда таблица велика, и нужно выполнить много запросов.Очевидно, что какая-то предварительная обработка может сэкономить много времени выполнения в таком случае.Я хотел бы показать довольно неясное, но элегантное решение 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.

4 голосов
/ 04 августа 2011

Кажется, что во всех ответах пропущена функция, которая почти специально предназначена для подобных ситуаций, а именно: 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 голосов
/ 04 августа 2011
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

2 голосов
/ 04 августа 2011

Это?

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

(поскольку я не могу просто вырезать и вставить tableA из вашего вопроса так, как он отформатирован, я не пробовал).

1 голос
/ 04 августа 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...