Classifying things into kinds

1 回表示 (過去 30 日間)
John Pryce
John Pryce 2020 年 12 月 5 日
コメント済み: John Pryce 2020 年 12 月 5 日
Increasingly often I want to do the following, so I want a simple vectorised way to do it - no "for" loops.
I have n things. Each thing is of one of m types. Coding the things as 1:n and the types as 1:m I can describe this data by an n-vector x where each x(j) is an integer in 1:m saying what type thing j has.
E.g. let n=7, m=5, then x = [2 3 1 3 5 1 2] says thing 1 has type 2, thing 2 has type 3 etc.
I want to convert between this form and the (obviously equivalent) form of a *partition* of 1:n into m subsets where the i'th subset lists all the things that have type i. This shall be a cell vector c of length m where c{i} is the set {j such that x(j)=i}, written as an ordinary vector in ascending order.
For the example, c is {[3], [1 7], [2 4], [] ,[5]}. Note c{4} is the empty vector because type 4 wasn't used.
Obviously, one can convert x to c and c to x by simple "for" loops but I want to avoid it.
I can do "x to c" by
c = arrayfun(@(i)find(x==i),1:m,'UniformOutput',false);
but (1) it looks clumsy, (2) implicitly it applies "find" to x a total of m times whereas a single pass through x should do.
Imagine n=10,000 and m=10, say. I welcome a better solution.
  2 件のコメント
John Pryce
John Pryce 2020 年 12 月 5 日
Sorry I should have written c is {[3 6], [1 7], [2 4], [] ,[5]}.
John Pryce
John Pryce 2020 年 12 月 5 日
Thanks! This is just what I was looking for.

サインインしてコメントする。

採用された回答

Ameer Hamza
Ameer Hamza 2020 年 12 月 5 日
編集済み: Ameer Hamza 2020 年 12 月 5 日
You can use accumarray()
x = [2 3 1 3 5 1 2];
c = accumarray(x(:), (1:numel(x)), [], @(x) {x})
Result
>> c{:}
ans =
3
6
ans =
1
7
ans =
2
4
ans =
[]
ans =
5

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeClassification Trees についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by