FOR함수를 간단하게 하는 방법

게시판 IDL Q&A FOR함수를 간단하게 하는 방법

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

      안녕하세요
      IDL 공부를 막 시작하고 있는 학생입니다.
      다름이 아니라 제가 파일을 읽고 FOR함수를 사용하는데 너무 길어지고, PRO를 실행하는데 너무 오랜 시간이 걸려서 어떻게 하면 더 간단하게 할 수 있을 지 궁금합니다!
      o3과 pm10의 월별 그래프를 그리려고 하여 월마다의 값이 필요합니다.

      처음에 o3mean(월)과 pm10mean(월)의 배열을 선언하고 for구문을 사용했습니다.

      o3mean1=dblarr(n_elements(code1)) & pm10mean1=dblarr(n_elements(code1))
      o3mean2=dblarr(n_elements(code1)) & pm10mean2=dblarr(n_elements(code1))
      o3mean3=dblarr(n_elements(code1)) & pm10mean3=dblarr(n_elements(code1))
      o3mean4=dblarr(n_elements(code1)) & pm10mean4=dblarr(n_elements(code1))
      o3mean5=dblarr(n_elements(code1)) & pm10mean5=dblarr(n_elements(code1))
      o3mean6=dblarr(n_elements(code1)) & pm10mean6=dblarr(n_elements(code1))
      o3mean7=dblarr(n_elements(code1)) & pm10mean7=dblarr(n_elements(code1))
      o3mean8=dblarr(n_elements(code1)) & pm10mean8=dblarr(n_elements(code1))
      o3mean9=dblarr(n_elements(code1)) & pm10mean9=dblarr(n_elements(code1))
      o3mean10=dblarr(n_elements(code1)) & pm10mean10=dblarr(n_elements(code1))
      o3mean11=dblarr(n_elements(code1)) & pm10mean11=dblarr(n_elements(code1))
      o3mean12=dblarr(n_elements(code1)) & pm10mean12=dblarr(n_elements(code1))

      for j=0l,n_elements(code1)-1 do begin
      o3mean1[j]=mean(a[j,where(strmid(timeo,8,2) eq 1)],/nan)
      o3mean2[j]=mean(a[j,where(strmid(timeo,8,2) eq 2)],/nan)
      o3mean3[j]=mean(a[j,where(strmid(timeo,8,2) eq 3)],/nan)
      o3mean4[j]=mean(a[j,where(strmid(timeo,8,2) eq 4)],/nan)
      o3mean5[j]=mean(a[j,where(strmid(timeo,8,2) eq 5)],/nan)
      o3mean6[j]=mean(a[j,where(strmid(timeo,8,2) eq 6)],/nan)
      o3mean7[j]=mean(a[j,where(strmid(timeo,8,2) eq 7)],/nan)
      o3mean8[j]=mean(a[j,where(strmid(timeo,8,2) eq 8)],/nan)
      o3mean9[j]=mean(a[j,where(strmid(timeo,8,2) eq 9)],/nan)
      o3mean10[j]=mean(a[j,where(strmid(timeo,8,2) eq 10)],/nan)
      o3mean11[j]=mean(a[j,where(strmid(timeo,8,2) eq 11)],/nan)
      o3mean12[j]=mean(a[j,where(strmid(timeo,8,2) eq 12)],/nan)
      endfor

      for j=0l,n_elements(code1)-1 do begin
      pm10mean1[j]=mean(b[j,where(strmid(timeo,8,2) eq 1)],/nan)
      pm10mean2[j]=mean(b[j,where(strmid(timeo,8,2) eq 2)],/nan)
      pm10mean3[j]=mean(b[j,where(strmid(timeo,8,2) eq 3)],/nan)
      pm10mean4[j]=mean(b[j,where(strmid(timeo,8,2) eq 4)],/nan)
      pm10mean5[j]=mean(b[j,where(strmid(timeo,8,2) eq 5)],/nan)
      pm10mean6[j]=mean(b[j,where(strmid(timeo,8,2) eq 6)],/nan)
      pm10mean7[j]=mean(b[j,where(strmid(timeo,8,2) eq 7)],/nan)
      pm10mean8[j]=mean(b[j,where(strmid(timeo,8,2) eq 8)],/nan)
      pm10mean9[j]=mean(b[j,where(strmid(timeo,8,2) eq 9)],/nan)
      pm10mean10[j]=mean(b[j,where(strmid(timeo,8,2) eq 10)],/nan)
      pm10mean11[j]=mean(b[j,where(strmid(timeo,8,2) eq 11)],/nan)
      pm10mean12[j]=mean(b[j,where(strmid(timeo,8,2) eq 12)],/nan)
      endfor

      이렇게 너무 길어졌는데요
      그래서 나름 시도를 해보려고 다음과 같이 해봤는데 에러가 납니다.
      for I=0,n_elements(code1)-1 do begin
      for k=1,12 do begin
      o3mean[k]=mean(a[i,where(strmid(timeo,8,2) eq k)],/nan)
      endfor
      endfor

      다른 방법이 없을까요?

    • #5226 Reply
      mwkim
      회원

      내용을 봐서는 a와 b라는 변수에 대해 timeo라는 시간 정보를 통해

      월별 평균을 구해 o3, pm10 이라는 변수로 저장하고자 하시는 것 같습니다.

      우선 올려주신 내용에서 몇 가지 조언(?)이나 질문을 드리면 다음과 같습니다.

      ——————————–
      1. 변수명
      o3나 pm10 평균 변수를 저장할 때, 굳이 이유가 없다면 o3mean1, o3mean2, … , o3mean12 로 만드시기보단
      o3mean 이라는 변수로 통합하고 해당 변수에 월별 저장을 위한 차원을 하나 더 두시는게 편합니다.
      ——————————–
      2. 반복 수행 시 차원 설정
      아마 아래 시도하신 반복문이 o3mean으로 통합하여 수행하시려고 시도한 것 같은데,
      이 경우 o3mean은 2차원으로 설정되어야 하며, 그렇지 않은 경우 제대로 안 될 것 같습니다.
      (아마 아래 코드는 i번째 차원 저장이 안 될 겁니다.)
      에러가 발생했다고 하셨는데 어떤 에러지 올려주시면 도움이 될지도…
      ——————————–
      3. WHERE 함수의 사용
      사용하실 때, 월별마다 하나의 자료가 반드시 있다면 문제가 없지만
      그렇지 않다면 IDL 버전에 따라 문제가 생길수도 있습니다.
      따라서 WHERE함수의 /NULL 옵션을 사용하거나 count를 통해 있는지 확인해야 합니다.
      ——————————–
      4. MEAN 함수의 사용
      아마도 a, b 자료는 2차원 자료로 생각되는데, 원하는 차원에 대해서만 평균할 때는
      DIMENSION 키워드를 사용하시면 됩니다.
      (자세한건 도움말 참조)
      ——————————–

      전체적으로 자료의 처리 방식에 대해서는 이해하고 계신듯하나,

      프로그램을 만드는 부분에 대해서는 조금 더 연습하시면 좋을 것 같습니다.

      아래는 제가 올려주신 코드를 기반으로 임의의 자료 생성해서 테스트한 코드입니다. 참고하세요.
      (정확한 목적은 몰라서 대충 파악한 의도만 반영)

      ——————————–

      PRO MONTHLY_MEAN

      dataLen = 50
      timeLen = 100
      time = CEIL(RANDOMU(seed,timeLen) * 12) ; timeo와 동일한 역할
      ; data = RANDOMU(seed,dataLen,timeLen) ; 완전 랜덤, a, b 자료와 동일한 역할
      data = RANDOMU(seed,dataLen,timeLen) + (FLTARR(dataLen,1)+1) # time ; 시간 경향 추가

      dataMonthMean = FLTARR(dataLen,12) ; o3mean, pm10mean 과 동일한 역할

      FOR iMonth = 0, 11 DO BEGIN
      idx = WHERE(time EQ iMonth+1,count)
      CASE count OF
      0:
      1: dataMonthMean[*,iMonth] = MEAN(data[*,idx],/NAN)
      ELSE: dataMonthMean[*,iMonth] = MEAN(data[*,idx],DIMENSION=2,/NAN)
      ENDCASE
      ENDFOR

      img1 = IMAGE(data,MARGIN=0,LAYOUT=[2,1,1]) ; 표출 확인
      img2 = IMAGE(dataMonthMean,MARGIN=0,LAYOUT=[2,1,2],/CURRENT) ; 표출 확인

      END

    • #5227 Reply
      shyang
      회원

      앗 제가 설명이 부족했네요
      많이 도움이 되었습니다! 참고해서 더욱 연습하겠습니다. 감사합니다. 🙂

2 답변 글타래를 보이고 있습니다
'FOR함수를 간단하게 하는 방법'에 답변달기
글쓴이 정보: