2014-12-24 2 views
0

나는 다음과 같은 테이블모양 변경 matlab에 테이블

name = ['A' 'A' 'A' 'B' 'B' 'C' 'C' 'C' 'C' 'D' 'D' 'E' 'E' 'E']'; 
value = randn(14, 1); 
T = table(name, value); 

내가, 전자에게 있습니다.

T = 

name  value 
____ _________ 

A  0.0015678 
A  -0.76226 
A   0.98404 
B   -1.0942 
B   0.71249 
C   1.688 
C   1.4001 
C   -0.9278 
C   -1.3725 
D   0.11563 
D  0.076776 
E   1.0568 
E   1.1972 
E   0.29037 

는 I는 다음의 방식으로 변환 할 : name에서 다른 값에 대응 value 처음 두 세포를 취하고 5x2 행렬에 넣어. 이 행렬은 다른 이름 인 A,B,C,D,E에 해당하는 행을 가지며 values에 해당하는 열을가집니다. 처음 두 행은 각각의 이름이 표에있는 값을 갖는 경우, 각각의 이름을 순환하고 각각의 셀 어레이에 이름마다 발생 제 두 값을 배치

0.0015678 -0.76226 
-1.0942 0.71249 

답변

3

사용자 지정 기능을 사용하여 accumarray으로이 작업을 수행 할 수 있습니다. 첫 번째 단계는 nameT을 숫자 벡터로 변환하는 것입니다. 그리고 accumarray을 적용 할 수 있습니다.

이 접근법은이 경우에만 accumarray (설명서에 표시되어 있음)을 보장하기 때문에 열 1에 따라 T을 정렬해야합니다. 따라서 T이 정렬되지 않을 수도 있지만 (예를 들어 있지만) sortrows을 사용하여 먼저 정렬하십시오.

T = sortrows(T, 1); %// you can remove this line if T is guaranteed to be sorted 
[~, ~, names] = unique(T(:,1)); %// names as a numeric vector 
result = cell2mat(accumarray(names, T.value, [], @(x) {x([1 2]).'})); 
+0

'accumarray'로 아주 잘 했어요! 여기에서 사용하는 것에 대해 생각하지 않았습니다. – rayryeng

3

우선도를 출력한다. 작업이 끝나면 매트릭스를 5 x 2으로 바꿉니다. 이와 같이 다음과 같이하십시오.

names = unique(T.name); %// 1 
ind = arrayfun(@(x) find(T.name == x), names, 'uni', 0); %// 2 
vals = cellfun(@(x) T.value(x(1:2)), ind, 'uni', 0); %// 3 
m = [vals{:}].'; %// 4 

각 코드 행을 천천히 살펴 보겠습니다.


라인 # 1

첫 번째 줄은 unique을 통해 모든 독특한 이름을 발견하고 우리는 names에 저장합니다.

라인 # 2

다음 줄은 고유 한 이름을 모두 통과하고 그 위치를 찾아/특정 이름을 공유하는 테이블의 행. arrayfun을 사용하고 각각의 이름을 names에두고, 우리가 찾고있는 것과 같은 이름을 가진 행을 찾고, 그 행 위치를 개별 셀에 배치합니다. 이들은 ind에 저장됩니다. 표에서 유효한 이름의 위치를 ​​찾으려면 find을 사용하고 위치가 열 벡터에 배치됩니다. 따라서 각 열 벡터가 개별 셀에 배치되는 5 개의 열 벡터를 갖게됩니다. 이 열 벡터는 테이블에있는 특정 이름과 일치하는 행을 알려줍니다.

라인 # 3

ind에서 각 셀을 통과하는 cellfun을 사용하여 특정 이름을 공유 처음 두 행의 위치를 ​​추출의 value 필드에 인덱스 테이블이 두 당겨 할 다음 행 값은 각 이름에 대해 개별 셀에 두 요소 벡터로 배치됩니다.

라인 # 4

코드의 마지막 줄은 단순히 각 2 요소의 벡터를 언 롤링합니다. 각 이름의 처음 두 요소는 에 저장됩니다. 그것들을 행으로 가져 오려면 단순히 언 롤링을 조 변경하십시오. 출력 행렬은 m에 저장됩니다.

m = 

    0.0016 -0.7623 
    -1.0942 0.7125 
    1.6880 1.4001 
    0.1156 0.0768 
    1.0568 1.1972 

내가 첫 번째 5를 보여 주었다 알린다 :


당신은 출력이, 어떻게 생겼는지보고 싶다면

내가 당신의 예를 들어 테이블 위의 코드를 실행할 때 내가 무엇을 얻을 끝자리에 약간의 반올림이 있으므로 정밀도의 자릿수. 그러나 이는 표시 목적으로 만 사용되므로 출력에 대한 예상과 동등합니다.


희망이 있습니다. 당신이 테이블을 사용하려면

+0

언제나처럼 완전하고 명확한 설명! –

+0

@ 루이스 멘도 내 친구 고마워! 메리 크리스마스! – rayryeng

+0

고마워요! 그리고 너도 마찬가지야! –

2

, 당신은 이런 식으로 뭔가를 시도 할 수 :

count = 1; 
U = unique(table2array(T(:,1))); 
for ii = 1:size(U,1) 
    A = find(table2array(T(:,1)) == U(ii)); 
    A = A(1:2); 
    B(count,1:2) = table2array(T(A,2)); 
    count = count + 1; 
end 

개인적으로, 나는 당신의 이름과 값을 배열로 할이 간단 찾아 테이블 잊어 것이다. 그것이 요구 사항이라면 나는 이해하지만, 나는 여전히 나의 해결책을 제공 할 것이다. 어느 쪽이든 통찰력을 제공 할 수 있습니다.

count = 1; 
U = unique(name); 
for ii = 1:size(U,1) 
    A = find(name == U(ii)); 
    A = A(1:2); 
    B(count,1:2) = value(A); 
    count = count + 1; 
end 

빠르고 빠르지 만 잘하면 충분합니다. 행운을 빕니다.

+0

두 번째 접근법은 내가했던 것과 거의 비슷하지만 '테이블'의 제약 조건을 유지하고 해당 필드를 참조하기 위해 점 표기법을 사용하기로 결정했습니다. +1 btw. – rayryeng

0

더 쉽게 관리하고 확장 할 수있는 또 다른 솔루션이 있습니다. MATLAB R2013b 이후로 테이블을 피벗 팅하기위한 특수 기능 (사용자가 원하는 기능)을 사용할 수 있습니다 : unstack. 그냥 같이 unstack을 사용하여 다음

name = ['A' 'A' 'A' 'B' 'B' 'C' 'C' 'C' 'C' 'D' 'D' 'E' 'E' 'E']'; 
value = randn(14, 1); 
rep = [1, 2, 3, 1, 2, 1, 2, 3, 4, 1, 2, 1, 2, 3]; 
T = table(name, value, rep); 

T = 

name  value  rep 
____ _________ ___ 

A   0.53767 1 
A   1.8339 2 
A   -2.2588 3 
B   0.86217 1 
B   0.31877 2 
C   -1.3077 1 
C  -0.43359 2 
C   0.34262 3 
C   3.5784 4 
D   2.7694 1 
D   -1.3499 2 
E   3.0349 1 
E   0.7254 2 
E  -0.063055 3 

:

당신이 원하는 것을 정확하게 취득하기 위하여는, 당신은 복제를 나타냅니다 테이블에 여분의 변수를 추가 할 필요가

pivotTable = unstack(T, 'value','name') 

pivotTable = 

    rep  A   B   C   D   E  
    ___ _______ _______ ________ _______ _________ 

    1  0.53767 0.86217  -1.3077  2.7694  3.0349 
    2  1.8339 0.31877 -0.43359 -1.3499  0.7254 
    3  -2.2588  NaN  0.34262  NaN -0.063055 
    4   NaN  NaN  3.5784  NaN   NaN 

이후에도 여전히 원하는 경우 re-arranging the table의 문제입니다.