Как сказали @High Performance Mark и @Nicholas Wilson, я бы начал с объединения двух списков через Transpose
или Thread
. В этом случае
In[1]:= Transpose[{clusterIndices, points}]==Thread[{clusterIndices, points}]
Out[1]:= True
В какой-то момент я посмотрел на то, что было быстрее, и я думаю, что Thread
немного быстрее. Но это действительно имеет значение, только если вы используете очень длинные списки.
@ High Performance Mark хорошо рекомендует Select
. Но это позволит вам вытащить только один кластер за раз. Код для выбора кластера 1 выглядит следующим образом:
Select[Transpose[{clusterIndices, points}], #[[1]]==1& ][[All, All, 2]]
Поскольку вы, похоже, хотите создать все кластеры, я бы предложил сделать следующее:
GatherBy[Transpose[{clusterIndices, points}], #[[1]]& ][[All, All, 2]]
, который имеет преимущество, состоящее в том, чтобы быть одним вкладышем, и единственная сложная часть заключалась в выборе правильного Part
из результирующего списка. Хитрость в определении количества All
терминов состоит в том, чтобы отметить, что
Transpose[{clusterIndices, points}][[All,2]]
требуется, чтобы получить очки обратно из транспонированного списка. Но «кластерный» список имеет один дополнительный уровень, следовательно, второй All
.
Следует отметить, что второй параметр в GatherBy
- это функция, которая принимает один параметр, и ее можно заменить любой функцией, которую вы хотите использовать. Таким образом, это очень полезно. Однако, если вы хотите трансформировать ваши данные во время их сбора, я бы посмотрел на Reap
и Sow
.
Редактировать: Reap
и Sow
немного используются и довольно мощные. Они несколько сбивают с толку, но я подозреваю, что GatherBy
реализован с использованием их внутри. Например,
Reap[ Sow[#[[2]], #[[1]] ]& /@ Transpose[{clusterIndices, points}], _, #2& ]
делает то же самое, что и мой предыдущий код, без хлопот по удалению индексов из точек. По сути, Sow
помечает каждую точку своим индексом, а затем Reap собирает все метки (_
для второго параметра) и выводит только точки. Лично я использую это вместо GatherBy, и я закодировал это в функцию, которую я загружаю, следующим образом:
SelectEquivalents[x_List,f_:Identity, g_:Identity, h_:(#2&)]:=
Reap[Sow[g[#],{f[#]}]&/@x, _, h][[2]];
Примечание: этот код является измененной формой того, что было в файлах справки в 5.x. Но файлы справки 6.0 и 7.0 удалили много полезных примеров, и это был один из них.