Как выполнить Tally-подобную операцию со списком на основе общего количества элементов в Mathematica - PullRequest
3 голосов
/ 19 декабря 2011

Например, у меня есть список вроде:

{{1, 2, 3}, {6}, {4, 5}, {1, 6}, {2, 2, 3, 2}, {9}, {7}, {2, 5}}

И я хочу получить подсчитанный список на основе суммы элементов списков.

В этом случае я хочу, чтобы вывод был:

{{6, {{1, 2, 3}, {6}}, {7, {{2, 5}, {1, 6}, {7}}}, {9, {{4, 5}, {2, 2, 3, 2}, {9}}}}}

Как это удобно сделать в Mathematica?

Большое спасибо.

Ответы [ 3 ]

5 голосов
/ 19 декабря 2011

Вот моя попытка - немного проще, чем у Йоды

lst = {{1, 2, 3}, {6}, {4, 5}, {1, 6}, {2, 2, 3, 2}, {9}, {7}, {2, 5}};

{Total@First@#, #} & /@ GatherBy[lst, Total]

Если вам не нужны повторяющиеся элементы, вы можете использовать

{Total@First@#, Union[#]} & /@ GatherBy[lst, Total]

Или, если вы действительно хотите подсчет-подобная операция

{Total@First@#, Tally[#]} & /@ GatherBy[lst, Total]
4 голосов
/ 19 декабря 2011

Хотя я, вероятно, сделал бы это так же, как @Simon, давайте не будем забывать, что Reap и Sow также могут использоваться:

Reap[Sow[#, Total[#]] & /@ lst, _, List][[2]]

, где lst - исходный список,Это будет несколько менее эффективно, чем код на основе GatherBy, но также довольно быстро.Можно ускорить вышеупомянутый код примерно в 1,5 раза, переписав его как

Reap[Sow @@@ Transpose[{lst, Total[lst, {2}]}], _, List][[2]]

, и в этом случае он становится примерно в 1,5 раза медленнее, чем код, основанный на GatherBy.Обратите внимание, что разница в скорости между этими двумя методами не очень существенна, потому что список разбит и поэтому не упакован, и GatherBy не имеет здесь преимущества в скорости, которым оно обычно обладает для упакованных массивов.

2 голосов
/ 19 декабря 2011

Не забывайте Tr.Это короче и быстрее:

{Tr@#, {##}} & @@@ GatherBy[lst, Tr]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...