비교 후 최댓값을 가진 변수 도출

게시판 IDL Q&A 비교 후 최댓값을 가진 변수 도출

태그: , ,

2 답변 글타래를 보이고 있습니다
  • 글쓴이
    • #2966 Reply
      sabugisl
      회원

      안녕하세요. 이전에 글 중에서 찾지 못해서 질문을 올립니다.

      2차원 변수 3가지(r(i,j), s(i,j), t(i,j))를 비교하여 각각의 i, j에서 최댓값을 가진 변수를 알고 싶은데요
      각 i, j 에서 최댓값을 가진 변수를 합쳐서 하나의 변수 (total(i,j)) 로 나타내고 싶습니다.
      예를 들어 r(i,j)가 가장 크면 1, s(i,j)가 가장크면 2.. 이런 식으로 각각의 i,j 마다 값을 부여하고 싶은데요..
      이 때 변수값이 동일하면 또 다른 숫자로 나타내고요.. (ex)4)
      max 함수는 하나의 변수 내에서 최댓값을 찾는 것 같더라고요.
      여타 책이나 다른 곳에서 아이디어를 얻을 수 없어서 질문 올립니다.
      가능한 함수나 방법이 있을까요?

    • #2967 Reply
      Jonghyuk
      회원

      세 개의 크기가 같은 2차원 배열 r, s, t가 다음과 같이 있는 상황입니다.

      r=randomu(seed, 4, 3)
      s=randomu(seed, 4, 3)
      t=randomu(seed, 4, 3)

      이러한 2차원 배열을 층으로 쌓아서 3차원 배열을 만들 떄 다음과 같이 할 수 있습니다.

      x=[[[r]], [[s]], [[t]]]

      참고로 xxx=[r, s, t] 와 같이 그냥 붙이면 1차원 방향으로(관념적으로 오른쪽으로 붙이기), xxx=[[r], [s], [t]] 와 같이 대괄호를 한번 감싸면 2차원 방향으로(관념적으로 아래로 붙이기), xxx[ [[r]], [[s]], [[t]] ] 와 같이 대괄호를 두 번 감싸면 3차원 방향으로(관념적으로 층으로 붙이기) 배열을 통합할 수 있습니다. 이러한 방법에 대해서 아래 링크를 보시면 좋습니다.
      http://blog.daum.net/swrush/166

      RANDOM으로 값을 만들었으니 상황마다 다르겠지만, 저는 다음과 같은 3차원 배열이 만들어졌습니다.

      IDL> print, x
      0.567786 0.761500 0.980104 0.0874583
      0.194464 0.410251 0.430641 0.0446276
      0.326077 0.687990 0.855732 0.0298006

      0.731714 0.524717 0.0772581 0.913978
      0.612994 0.137836 0.00728686 0.153460
      0.436454 0.989235 0.201311 0.608019

      0.596287 0.320769 0.0136553 0.968783
      0.768057 0.723100 0.473770 0.752396
      0.864415 0.512420 0.0393057 0.740206

      맨 위의 4*3 배열이 0층(사실상 r변수), 두번째 4*3 배열이 1층(s 변수), 세번째 4*3 배열이 2층(t 변수)입니다.

      MAX 함수에는(당연히 MIN 함수도) DIMENSION 이라는 키워드가 있어서 최대값을 결정하는 방향을 지정할 수 있습니다. 예를 들어 DIMENSION=3 이라고 하면 3차원 방향으로 최대값을 찾습니다.

      IDL> mx=max(x, dimension=3)

      IDL> print, mx
      0.731714 0.761500 0.980104 0.968783
      0.768057 0.723100 0.473770 0.752396
      0.864415 0.989235 0.855732 0.740206

      일단 이런 식으로 세 개의 2차원 배열에서 각 좌표의 최대값을 찾을 수 있겠습니다.

      다음으로, IDL의 MAX(또는 MIN) 함수에는 두 개의 인자를 줄 수 있습니다. 첫 인자는 최대값을 찾는 대상이고, 두 번째 인자는 변수로 세팅해야 하는데, 이 변수에 “최대값(또는 최소값)의 위치”를 알려줍니다. 이렇게 사용하실 수 있는것입니다.

      IDL> mx=max(x, wh_mx, dimension=3)

      이렇게 하면 두번째 인자 wh_mx 에 “최대값이 있는 곳(index 번호)”이 저장됩니다.

      IDL> print, wh_mx
      12 1 2 27
      28 29 30 31
      32 21 10 35

      IDL의 배열 인덱싱은 차원에 상관없이 첫번째 Element를 0번으로 시작해서 1씩 증가하도록 하는 체계가 있습니다. 3*4 배열 3개를 다루니까, 이 상황에서는 36개의 요소가 있고, 0부터 35번까지 인덱스 번호를 가지게 됩니다. 이는 N 차원에 무관하게 배열을 다루고자 하는 프로그래밍의 편의성을 가지기 위한 체계인데, 사람이 이해하기는 조금 덜 편한 점은 있습니다. 이에 대한 이해는 다음 링크를 보시면 좋습니다.

      http://blog.daum.net/swrush/183

      어쨌든, 최대값은 r, s, t 중 누가 가지고 있는가를 알고자 하면, 위 번호를 2차원 배열 개수 (여기서는 3*4)로 나눈 몫(정수부)을 계산하여 알 수 있습니다.

      IDL> print, wh_mx / (n_elements(r))
      1 0 0 2
      2 2 2 2
      2 1 0 2

      좌표 (0, 0) 왼쪽 상단은 s 변수에 최대값이 있고(값 1의 의미), 좌표 (3, 2) 우측 하단은 t 변수에 최대값이 있습니다(값 2의 의미).

      요약 : 같은 크기의 2차원 배열을 3차원으로 통합하면 편해지는 경우가 있습니다. MAX나 MIN 함수에 DIMENSION 키워드를 이용하여 특정 차원 방향의 최대,최소를 찾을 수 있습니다. MIN이나 MAX 함수의 두번째 인자는 해당 최소,최대값의 위치(index)를 알려줍니다.

      • 이 답변은 Jonghyuk에 의해 7 years, 5 months 전에 수정됐습니다.
    • #2969 Reply
      mwkim
      회원

      안녕하세요, 위에 잘 설명해주셔서 숟가락만 얹어봅니다.

      질문 내용 중에 최대값이 여러 개이면 그것 또한 별도로 나타낼 수 있는 방법도 추가로 물어보셨는데,

      다음과 같은 코드를 통해 해결할 수 있었습니다(위의 내용을 조금 변경했습니다.)

      ==============================

      r=FIX(RANDOMU(seed, 3, 4)*10) ; 중복값을 만들기 위해 정수로 변환
      s=FIX(RANDOMU(seed, 3, 4)*10) ; 중복값을 만들기 위해 정수로 변환
      t=FIX(RANDOMU(seed, 3, 4)*10) ; 중복값을 만들기 위해 정수로 변환

      x=[[[r]], [[s]], [[t]]]
      mx=MAX(x, wh_mx, dimension=3)
      find_layer = wh_mx / (N_ELEMENTS(r))

      FOR i = 0, 1 DO BEGIN
      x[wh_mx] = min_value ; min_value = -1로 사전 정의
      mx_temp=MAX(x, wh_mx, dimension=3)
      find_layer_temp = wh_mx / (N_ELEMENTS(r)) + 2 – i ; 인덱스 부여를 위해 일정값 추가
      wh_over=WHERE(mx NE mx_temp, count)
      IF count EQ N_ELEMENTS(r) THEN BREAK ; 중복값없는 경우 반복 실행 중단
      IF count NE 0 THEN BEGIN
      find_layer_temp[wh_over] = 0 ; 중복이 안 된 위치는 기존 인덱스 유지
      ENDIF
      find_layer += find_layer_temp ; 인덱스를 더하여 중복이 있는 경우 인덱스 증가
      ENDFOR

      PRINT, find_layer

      ==============================

      전체적인 흐름은 이전에 찾은 최대값(mx)을 사용자가 정의한 값(min_value)으로 바꾸고
      다시 최대값(mx_temp)을 찾아서 이전에 찾은 값과 비교하는 방식입니다.
      위와 같이 진행 시, 인덱스는 0~6까지 나오며 각 의미는 다음과 같습니다.
      0: r 행렬, 1: s 행렬, 2: t 행렬, 3: r,s 행렬, 4: r,t 행렬 5: s,t 행렬, 6: r,s,t 행렬
      에 최대값 존재입니다.

      이러한 방법은 해결방법이 이 외에도 많을 것으로 생각됩니다.
      (아마 검색해보면 이미 기능이 있거나 누군가 알고리즘이나 함수로 만들어 인터넷에 올려놨을 것 같습니다.)

      간단한 경우면 그냥 사용하셔도 되겠지만 자료가 큰 경우는 효율적인 알고리즘을 검색해보시는 걸 추천합니다.

2 답변 글타래를 보이고 있습니다
'비교 후 최댓값을 가진 변수 도출'에 답변달기
글쓴이 정보: