안녕하세요. 2015년이 밝았습니다. 여러분 모두 새해 복 많이 받으시고, 하시는 일 잘 되고, 행복하시길 바랍니다.
오늘은 2015년도 첫 게시물로서 WHERE 함수에 관한 얘기를 좀 해보겠습니다. 다들 잘 아시다시피 WHERE는 IDL의 꽃이라고 부를만한 함수입니다. 저도 여기저기서 IDL 교육을 할 때, "WHERE 함수를 잘 모르면 IDLer라 할 수 없다"라는 과장섞인 주장을 종종 할 정도입니다. 오늘은 이 WHERE 함수의 사용에 있어서 약간 주의가 필요한 부분에 대한 언급을 해보고자 합니다. WHERE 함수는 어떤 배열내에서 내가 원하는 조건을 만족하는 원소들의 인덱스를 추출하는 역할을 합니다. 일단 다음의 예를 봅시다.
IDL> arr = INDGEN(10)+1
여기서 만든 arr이란 배열은 1부터 10까지의 정수들 10개를 담고 있습니다. 여기서 값이 7인 원소값의 인덱스를 뽑아내려면 다음과 같이 하면 됩니다.
IDL> ww = WHERE(arr EQ 7)
IDL> PRINT, ww
그러면 ww는 arr 배열내에서 7이란 값의 위치에 해당되는 인덱스인 6을 갖게 된다는 것을 출력결과를 통해 바로 확인할 수 있습니다. 그런데 이 ww를 다음과 같이 HELP문으로 확인해보면 ww가 구체적으로 어떤 형태를 갖는지를 알 수 있는데요.
IDL> HELP, ww
ww LONG = Array[1]
이 결과를 보면 ww는 6이라는 숫자를 갖는 scalar값이 아니고, 6이란 숫자 한 개로 이루어진 배열로 인식되어 있음을 알 수 있습니다. 사실 이 부분이 좀 의외로 다가올 수 있습니다. 따라서 결과가 한 개면 그냥 하나짜리 scalar값으로 나오리라 지레 짐작하고 이후의 작업을 수행하다가 예기치않은 실수가 나올 가능성이 있습니다. 즉, 예를 들어 새로운 배열인 num을 다음과 같이 만들고, ww를 이 배열에 더한다고 합시다.
IDL> num = INTARR(5)
IDL> PRINT, num+ww
6
만약 ww가 6이라는 scalar값이라면 num의 배열 모든 원소들에 동등하게 더해지기 때문에 그 결과는 6, 6, 6, 6, 6같이 나올거라 예상할 수도 있겠지만, 막상 해보면 위와 같이 그냥 6이라는 값 하나만 달랑 출력됩니다. 그 이유는 WHERE가 돌려주는 결과는 갯수에 상관없이 무조건 배열의 형태로 산출되기 때문입니다. 갯수가 오직 한 개라도 마찬가지입니다. 따라서 결과가 단 하나일 경우 이 값이 scalar일 것으로 예상하고 이후의 작업을 수행하다보면 위의 예에서 본 것과 같이 전혀 의도하지 않았던 결과가 나올 수도 있습니다. 차라리 오류라도 나오면 뭔가 문제가 있나보다 하면서 수정을 하겠지만, 프로그램 로직상 오류도 전혀 안나올 경우에는 나도 모르는 사이에 이상한 방향으로 작업이 진행될 수도 있다는 얘기입니다. 물론 결과가 여러 개일 경우는 당연히 배열의 형태일 것으로 예측 가능하겠지요. 하지만 결과가 단 하나일 경우가 이와 같이 혼동의 여지가 좀 있습니다.
이것은 IDL의 WHERE 함수의 특성이기 때문에 사용자 입장에서 직접적으로 어떻게 할 방법은 없습니다. 다만 사용자의 입장에서는 WHERE의 결과의 갯수를 체크해서 경우에 따른 작업 분기를 설정해주는 것이 현실적으로 가장 무난한 방법입니다. 다음과 같이 WHERE 함수의 결과의 갯수를 돌려주는 인자를 하나 사용하고, 이 값이 한 개일 경우 및 그 이상일 경우를 구분해주는 방법이 가장 무난하다고 봅니다.
IDL> ww = WHERE(arr EQ 7, count)
IDL> IF count EQ 1 THEN PRINT, num+ww[0]
이와 같이 WHERE의 결과가 단 하나일 경우에는 ww 대신 ww[0]이라고 명시함으로써 불필요한 혼동을 제거하는 방식입니다. 지금 제시된 예제가 약간 부자연스럽게 보일 수도 있지만, 핵심은 WHERE의 결과가 여러 개, 단 한 개, 또는 아예 없을 경우 등에 대한 구분을 해주는 것이 바람직하다는 것입니다. 같은 맥락으로 본다면, count가 0일 경우는 해당사항이 아예 없는 경우이기 때문에, 이럴 경우에는 또 어떤 식으로 처리할 것인가에 대한 명시를 해주는 것도 좋겠지요. 즉, count가 0일 경우에는 ww가 그냥 -1이라는 scalar값으로 되돌려지기 때문에 이런 경우에 대한 대처도 필요할 경우가 있다는 점을 유념하시면 좋겠습니다.
'IDL > Programming' 카테고리의 다른 글
| LAMBDA, LAMBDAP 함수 소개 [1] (0) | 2015.02.02 |
|---|---|
| 새로운 배열 생성 방법 소개 (0) | 2015.01.30 |
| 특정 년, 월의 일수(number of days) 산출법 (0) | 2014.10.17 |
| 날짜 문자열 갖고 놀기 [1] (0) | 2014.10.16 |
| 함수(Function)에서 여러 개의 값들을 한꺼번에 되돌려주는 방법 (0) | 2014.09.11 |