2016-09-29 3 views
0

특정 필드가있는 구조체 배열이 있습니다. 이제 특정 필드가 비어있는 모든 행을 필터링하려고합니다.특정 필드가 비어있을 때 구조체 배열의 데이터를 필터링하는 방법

은 기본적으로 제가 지금 가지고있는 것은 :

data(1).elem1 = 1; 
data(1).elem2 = 2; 
data(1).elem3 = 3; 
data(2).elem1 = 4; 
data(2).elem3 = 6; 
data(3).elem1 = 7; 
data(3).elem2 = 8; 
data(4).elem1 = 9; 
data(4).elem2 = 10; 
data(4).elem3 = 11; 
data(5).elem1 = 9; 
data(5).elem3 = 11; 

data 

fields = {'elem2,elem3'}; 

data(any(~cellfun(@(x) any(~isempty(x)), {data.('elem2'); data.('elem3')}))) = []; 

이 괜찮 작동합니다. 그러나 특별히 {data.('elem2'); data.('elem3')}을 표현하고 싶지 않습니다. 간단히 변수 fields을 사용하고 싶습니다.

필드 주위를 반복하여 {data.('elem2'); data.('elem3')}을 포함하는 임시 변수를 만들 수 있습니다. 그러나 나는 이것을하지 않는 것을 선호한다. 나는 더 영리한 방법이 있다고 생각하기 때문에 나는 현재하고있는 것처럼 더 효율적으로 할 수 없는지 궁금해하고 있습니다.

+0

'fields'를 정의하는 데 실수가 있습니다. 'fields = { 'elem2', 'elem3'};'이어야합니다. 그런 다음 당신은'data (any (cellfun (@ (x) isempty (x), {data. (fields {1}), data. (필드 {2})}})) = [];' 하나의 추가 '임의'및 2 개의 추가 부정)! – erfan

답변

2

구조체를 셀로 변환하고 cellfun을 사용하여 의 빈 값을 확인하고 필드를 확인할 수 있습니다. 그런 다음 ismember을 사용하여 확인할 필드의 색인을 찾으십시오.

fields = {'elem2','elem3'}; 
emptyIdx = squeeze(cellfun('isempty', struct2cell(data))); 
idxToRemove = any(emptyIdx(ismember(fieldnames(data), fields),:), 1); 

예 :

data(1).elem1 = 1; 
data(1).elem2 = 2; 
data(1).elem3 = 3; 
data(2).elem1 = 4; 
data(2).elem3 = 6; 
data(3).elem1 = 7; 
data(3).elem2 = 8; 
data(4).elem1 = 2; 
data(4).elem3 = 5; 
data(4).elem2 = 4; 

만 인덱스 1 (4) 여기서

data = 
1x2 struct array with fields: 
    elem1 
    elem2 
    elem3 
+0

코드의 일부를 사용할 수 있다고 생각하지만 코드가 원하는대로 작동하지 않으면 예제 데이터 세트로 테스트 해보십시오. 요소를 제거하지는 않습니다. –

+0

코드는 실제로 '데이터'의 요소가 아닌 필드를 필터링합니다. 추가 된 데이터 세트로 코드를 시험해보십시오. 요소 수가 필드 수와 같아서 효과가 있었던 이유입니다. –

+1

@ WG- 진실하고 혼합 된 행과 열. 'squeeze'를 사용하여 내 솔루션을 업데이트했습니다. – NLindros

0

와의 데이터 구조체를 제공

I=ismember(fieldnames(data), {'elem2', 'elem3'}); 
data(~arrayfun(@(x) any(I & structfun(@isempty, x)), data))=[]; 

그것을 수행하는 방법 중 하나의 인덱스 찾기는 관심 분야. 을 사용하여 data의 모든 요소를 ​​반복 한 다음 structfun을 사용하여 모든 필드를 반복하고 I & ...에 관심이없는 필드는 무시하십시오.

관련 문제