반응형

Android에서 화면을 회전하면 기본적으로 Activity가 다시 만들어진다. 그래서 회전 처리는 단순히 가로/세로 레이아웃을 바꾸는 문제가 아니라, 사용자가 보던 상태를 저장하고 다시 복원하는 문제에 가깝다. 입력값, 스크롤 위치, 선택된 탭, 로딩 중인 데이터가 여기에 포함된다.

onConfigurationChanged를 쓰면 재생성을 피할 수 있지만, 모든 상황에서 좋은 답은 아니다. 대부분의 화면은 Activity 재생성을 자연스러운 흐름으로 받아들이고, 상태 복원 구조를 갖추는 편이 유지보수에 유리하다.

Android 화면 회전 처리: onCreate 재호출과 onConfigurationChanged 기준 검색, 들여쓰기, 탭, 상태바 설정 흐름
Android 화면 회전 처리: onCreate 재호출과 onConfigurationChanged 기준 핵심 설정 흐름

두 가지 처리 방식 비교

방식 어울리는 경우 주의할 점
기본 재생성 일반 화면, 폼, 목록, 상세 화면 상태 저장과 복원 경로가 필요하다.
onConfigurationChanged 카메라, 영상, 특수 렌더링 화면 직접 리소스와 레이아웃 변화를 처리해야 한다.
회전 고정 키오스크, 단일 방향 UX가 명확한 화면 문제 회피로 쓰면 태블릿과 폴더블 대응이 약해진다.

기본 재생성을 기준으로 상태 복원하기

간단한 화면 상태는 Bundle에 저장하고, 화면보다 오래 살아야 하는 데이터는 ViewModel에 둔다. 둘을 구분하면 회전뿐 아니라 프로세스 종료 후 복원까지 더 안정적으로 다룰 수 있다.

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putString("query", binding.searchInput.text.toString())
    outState.putInt("selectedTab", binding.tabs.selectedTabPosition)
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val query = savedInstanceState?.getString("query").orEmpty()
    val selectedTab = savedInstanceState?.getInt("selectedTab") ?: 0
    render(query, selectedTab)
}

onConfigurationChanged는 우회로가 아니다

manifest에 configChanges를 추가하면 Activity 재생성을 막을 수 있지만, 그 대신 개발자가 리소스 변경, 레이아웃 갱신, 상태 업데이트를 직접 책임져야 한다. 특별한 이유가 없으면 기본 생명주기 안에서 해결하는 편이 안전하다.

점검 체크리스트

  • 회전 후 입력 중이던 텍스트와 선택 상태가 유지되는지 확인한다.
  • 목록 화면은 스크롤 위치가 지나치게 튀지 않는지 본다.
  • API 재호출이 필요 이상으로 반복되지 않는지 로그로 확인한다.
  • 가로 레이아웃이 따로 있다면 같은 상태 데이터를 공유하는지 테스트한다.
  • 회전 고정은 UX 이유가 분명할 때만 선택한다.

읽을 때 확인할 점

화면 회전 처리는 어떤 콜백을 쓰느냐보다, 재생성돼도 화면이 무너지지 않는가가 핵심이다. Activity 생명주기를 자연스럽게 통과하도록 만들면 회전, 다크 모드 전환, 언어 변경 같은 다른 configuration change에도 같은 구조를 쓸 수 있다.

함께 보면 좋은 글

반응형
반응형

grep 명령어 사용법: 문자열 검색과 자주 쓰는 옵션를 읽을 때는 용어를 외우는 것보다 먼저 구분 기준을 잡는 편이 좋다. 비슷해 보이는 항목도 권리, 입력, 사용 목적, 확인 절차를 나눠 보면 실제로 어디가 다른지 훨씬 빨리 보인다.

아래 보강은 본문을 표와 절차 중심으로 다시 읽을 수 있게 만든 것이다. 독자가 글을 끝까지 읽지 않아도 핵심 비교 기준과 적용 순서를 한 번에 확인할 수 있도록 구성했다.

grep 명령어 사용법: 문자열 검색과 자주 쓰는 옵션 핵심 개념 흐름
grep 명령어 사용법: 문자열 검색과 자주 쓰는 옵션 핵심 흐름

핵심 흐름 한눈에 보기

구분 확인할 것 읽을 때 주의할 점
-n 줄 번호 출력 코드나 로그 위치를 바로 찾아갈 때 쓴다.
-i 대소문자 무시 ERROR, error가 섞여 있을 때 유용하다.
-r 디렉터리 재귀 검색 프로젝트 전체에서 키워드를 찾을 때 쓴다.
-v 매칭 제외 노이즈가 되는 줄을 빼고 볼 때 쓴다.

작게 적용해 보는 순서

개념을 바로 큰 문제에 적용하기보다 작은 질문으로 나누면 이해가 오래 간다. 다음처럼 정의, 조건, 판단을 분리해서 적어 보면 본문에서 놓친 부분을 빨리 찾을 수 있다.

grep -n "ERROR" app.log
grep -ri "TODO" src/
ps aux | grep node

처음부터 정규식으로 복잡하게 가지 않는다

먼저 단순 문자열로 결과 범위를 확인한 뒤, 필요한 경우에만 정규식과 제외 조건을 붙이는 편이 빠르다.

체크리스트

  • 첫 문단만 읽고도 이 글이 해결하는 문제가 무엇인지 말할 수 있는지 확인한다.
  • 표의 구분 기준을 내 상황에 그대로 적용할 수 있는지 본다.
  • 비슷한 용어가 나오면 권리, 입력, 출력, 사용 목적 중 어느 축이 다른지 표시한다.
  • 실제 적용 전에는 작은 예시 하나로 결과가 기대와 맞는지 확인한다.
반응형
반응형

ES6 모듈과 JavaScript 문법 변화 정리를 읽을 때는 용어를 외우는 것보다 먼저 구분 기준을 잡는 편이 좋다. 비슷해 보이는 항목도 권리, 입력, 사용 목적, 확인 절차를 나눠 보면 실제로 어디가 다른지 훨씬 빨리 보인다.

아래 보강은 본문을 표와 절차 중심으로 다시 읽을 수 있게 만든 것이다. 독자가 글을 끝까지 읽지 않아도 핵심 비교 기준과 적용 순서를 한 번에 확인할 수 있도록 구성했다.

ES6 모듈과 JavaScript 문법 변화 정리 핵심 개념 흐름
ES6 모듈과 JavaScript 문법 변화 정리 핵심 흐름

핵심 흐름 한눈에 보기

구분 확인할 것 읽을 때 주의할 점
export 함수, 클래스, 상수를 밖으로 공개 기본 export와 named export를 섞을 때 이름을 확인한다.
import 다른 파일의 공개 값을 사용 경로와 확장자 처리 방식이 실행 환경마다 다를 수 있다.
scope 모듈 파일은 자체 스코프를 가짐 전역에 자동으로 붙는다고 기대하지 않는다.

작게 적용해 보는 순서

개념을 바로 큰 문제에 적용하기보다 작은 질문으로 나누면 이해가 오래 간다. 다음처럼 정의, 조건, 판단을 분리해서 적어 보면 본문에서 놓친 부분을 빨리 찾을 수 있다.

// math.js
export const add = (a, b) => a + b;
// app.js
import { add } from './math.js';

모듈은 파일을 나누는 문법보다 의존성을 드러내는 장치다

어떤 파일이 무엇을 제공하고 무엇을 필요로 하는지 보이면 리팩터링과 테스트가 쉬워진다.

체크리스트

  • 첫 문단만 읽고도 이 글이 해결하는 문제가 무엇인지 말할 수 있는지 확인한다.
  • 표의 구분 기준을 내 상황에 그대로 적용할 수 있는지 본다.
  • 비슷한 용어가 나오면 권리, 입력, 출력, 사용 목적 중 어느 축이 다른지 표시한다.
  • 실제 적용 전에는 작은 예시 하나로 결과가 기대와 맞는지 확인한다.
반응형
반응형

안드로이드 개발 기본 개념: Activity, View, 생명주기를 읽을 때는 용어를 외우는 것보다 먼저 구분 기준을 잡는 편이 좋다. 비슷해 보이는 항목도 권리, 입력, 사용 목적, 확인 절차를 나눠 보면 실제로 어디가 다른지 훨씬 빨리 보인다.

아래 보강은 본문을 표와 절차 중심으로 다시 읽을 수 있게 만든 것이다. 독자가 글을 끝까지 읽지 않아도 핵심 비교 기준과 적용 순서를 한 번에 확인할 수 있도록 구성했다.

안드로이드 개발 기본 개념: Activity, View, 생명주기 핵심 개념 흐름
안드로이드 개발 기본 개념: Activity, View, 생명주기 핵심 흐름

핵심 흐름 한눈에 보기

구분 확인할 것 읽을 때 주의할 점
onCreate 화면 초기 생성 무거운 작업을 직접 오래 붙잡지 않는다.
onPause 다른 화면으로 가려짐 입력 상태나 임시 작업을 잃지 않게 정리한다.
onResume 다시 전면 표시 화면 데이터가 최신인지 확인한다.

작게 적용해 보는 순서

개념을 바로 큰 문제에 적용하기보다 작은 질문으로 나누면 이해가 오래 간다. 다음처럼 정의, 조건, 판단을 분리해서 적어 보면 본문에서 놓친 부분을 빨리 찾을 수 있다.

onCreate -> view binding
onPause -> save transient state
onResume -> refresh visible data

생명주기는 예외 상황이 아니라 기본 동작이다

회전, 앱 전환, 권한 창처럼 흔한 상황에서 화면이 다시 만들어질 수 있다는 전제로 작성해야 한다.

체크리스트

  • 첫 문단만 읽고도 이 글이 해결하는 문제가 무엇인지 말할 수 있는지 확인한다.
  • 표의 구분 기준을 내 상황에 그대로 적용할 수 있는지 본다.
  • 비슷한 용어가 나오면 권리, 입력, 출력, 사용 목적 중 어느 축이 다른지 표시한다.
  • 실제 적용 전에는 작은 예시 하나로 결과가 기대와 맞는지 확인한다.
반응형
반응형

setuptools는 Python 프로젝트를 패키지로 묶고 설치할 수 있게 해 주는 도구다. 라이브러리를 재사용 가능한 형태로 만들 때 기본 개념을 알아 두면 좋다.

패키징에서 다루는 정보

  • 프로젝트 이름, 버전, 설명, 의존성, 포함할 패키지 목록을 메타데이터로 정의한다.
  • 소스 코드 디렉터리와 배포 파일에 포함할 파일을 구분한다.
  • 설치 후 실행 가능한 콘솔 명령을 entry point로 등록할 수 있다.

현재 기준의 흐름

  • 새 프로젝트는 pyproject.toml을 중심으로 빌드 설정을 두는 방식이 일반적이다.
  • setuptools는 여전히 널리 쓰이며, build와 pip를 통해 설치 파일을 만들고 검증할 수 있다.
  • 오래된 setup.py 직접 실행 방식은 가능하면 최신 빌드 흐름으로 바꾸는 편이 좋다.

확인할 부분

  • 패키지 이름과 import 이름이 다를 수 있으므로 설치 후 실제 import를 테스트한다.
  • 버전 번호는 배포 이력 관리와 문제 재현에 중요하다.
  • 의존성 범위를 너무 넓게 잡으면 설치 충돌이 생길 수 있고, 너무 좁으면 업그레이드가 어려워진다.

읽을 때 확인할 점

Python setuptools: 패키지 설치와 배포 구조 이해하기를 볼 때는 먼저 용어의 정의와 적용 조건을 분리해서 보는 것이 좋다. 같은 표현이라도 개발 환경, 데이터 형태, 사용 목적에 따라 실제 의미가 달라질 수 있기 때문이다.

  • 지금 해결하려는 문제가 개념 이해인지, 구현 적용인지, 결과 해석인지 먼저 나눈다.
  • 예제의 전제 조건이 내 상황과 같은지 확인한 뒤 필요한 부분만 가져온다.
  • 결과가 기대와 다르면 입력, 설정, 경계 조건을 순서대로 좁혀서 확인한다.

적용 체크리스트

  • 핵심 용어를 한 문장으로 설명할 수 있는지 확인한다.
  • 작은 예제나 샘플 데이터로 동작을 먼저 검증한다.
  • 실제 적용 전에는 입력 조건, 예외 케이스, 결과 해석 기준을 따로 적어 둔다.

함께 보면 좋은 글

마무리

Python setuptools: 패키지 설치와 배포 구조 이해하기는 개념 자체보다 적용 상황과 한계를 함께 보는 것이 중요하다. 작은 예제로 동작을 확인하고, 실제 환경에서는 입력 조건과 예외 케이스를 따로 점검하는 습관을 두면 시행착오를 줄일 수 있다.

반응형
반응형

Python의 super()는 부모 클래스를 직접 지목하는 문법이 아니라, 메서드 탐색 순서인 MRO를 따라 다음 구현을 호출하는 도구다.

super()가 하는 일

  • 단일 상속에서는 부모 클래스의 메서드를 호출하는 것처럼 보인다.
  • 다중 상속에서는 클래스 선언 순서와 MRO에 따라 다음 클래스가 결정된다.
  • 따라서 부모 클래스 이름을 직접 쓰는 방식보다 협력적 다중 상속에 잘 맞는다.

MRO를 확인하는 방법

  • 클래스의 __mro__ 속성이나 mro() 메서드를 보면 탐색 순서를 확인할 수 있다.
  • 예상과 다른 메서드가 호출된다면 상속 선언 순서를 먼저 점검한다.
  • 모든 클래스가 같은 메서드 시그니처를 따르도록 맞추면 super() 호출 흐름이 안정된다.

주의할 점

  • 다중 상속에서 특정 부모를 직접 호출하면 같은 초기화 코드가 중복 실행될 수 있다.
  • __init__에서 super()를 쓸 때는 인자 전달 방식을 일관되게 설계해야 한다.
  • 상속 구조가 복잡해진다면 조합이나 명시적 위임이 더 단순한 해법일 수 있다.

읽을 때 확인할 점

Python super()와 MRO: 상속 호출 순서 이해하기를 볼 때는 먼저 용어의 정의와 적용 조건을 분리해서 보는 것이 좋다. 같은 표현이라도 개발 환경, 데이터 형태, 사용 목적에 따라 실제 의미가 달라질 수 있기 때문이다.

  • 지금 해결하려는 문제가 개념 이해인지, 구현 적용인지, 결과 해석인지 먼저 나눈다.
  • 예제의 전제 조건이 내 상황과 같은지 확인한 뒤 필요한 부분만 가져온다.
  • 결과가 기대와 다르면 입력, 설정, 경계 조건을 순서대로 좁혀서 확인한다.

적용 체크리스트

  • 핵심 용어를 한 문장으로 설명할 수 있는지 확인한다.
  • 작은 예제나 샘플 데이터로 동작을 먼저 검증한다.
  • 실제 적용 전에는 입력 조건, 예외 케이스, 결과 해석 기준을 따로 적어 둔다.

함께 보면 좋은 글

마무리

Python super()와 MRO: 상속 호출 순서 이해하기는 개념 자체보다 적용 상황과 한계를 함께 보는 것이 중요하다. 작은 예제로 동작을 확인하고, 실제 환경에서는 입력 조건과 예외 케이스를 따로 점검하는 습관을 두면 시행착오를 줄일 수 있다.

반응형
반응형

Jupyter Notebook은 코드, 실행 결과, 설명을 한 화면에 함께 남길 수 있는 작업 환경이다. 데이터 분석이나 실험 과정을 기록하기에 특히 편하다.

기본 사용 흐름

  • 코드는 셀 단위로 작성하고 실행한다. 실행 순서가 결과에 영향을 주므로 셀 번호를 확인해야 한다.
  • Markdown 셀을 함께 쓰면 실험 목적, 변수 의미, 결과 해석을 코드 옆에 남길 수 있다.
  • 그래프는 셀 출력으로 바로 확인할 수 있어 데이터 분포와 모델 결과를 빠르게 비교하기 좋다.

디버깅할 때 보는 것

  • 변수가 어디에서 정의되었는지, 같은 이름을 다시 덮어쓴 적은 없는지 확인한다.
  • 긴 노트북은 위에서부터 순서대로 다시 실행해 재현성을 점검한다.
  • 에러가 난 셀만 보지 말고 그 전에 실행된 데이터 로딩과 전처리 셀도 함께 본다.

관리 팁

  • 실험용 노트북과 배포용 스크립트는 분리하는 편이 좋다.
  • 출력 결과가 너무 커지면 파일 크기가 커지고 버전 관리가 어려워질 수 있다.
  • 중요한 분석은 데이터 경로와 패키지 버전을 함께 기록해 둔다.

읽을 때 확인할 점

Jupyter Notebook 사용법: 셀 실행, 그래프 출력, 디버깅를 볼 때는 먼저 용어의 정의와 적용 조건을 분리해서 보는 것이 좋다. 같은 표현이라도 개발 환경, 데이터 형태, 사용 목적에 따라 실제 의미가 달라질 수 있기 때문이다.

  • 지금 해결하려는 문제가 개념 이해인지, 구현 적용인지, 결과 해석인지 먼저 나눈다.
  • 예제의 전제 조건이 내 상황과 같은지 확인한 뒤 필요한 부분만 가져온다.
  • 결과가 기대와 다르면 입력, 설정, 경계 조건을 순서대로 좁혀서 확인한다.

적용 체크리스트

  • 핵심 용어를 한 문장으로 설명할 수 있는지 확인한다.
  • 작은 예제나 샘플 데이터로 동작을 먼저 검증한다.
  • 실제 적용 전에는 입력 조건, 예외 케이스, 결과 해석 기준을 따로 적어 둔다.

함께 보면 좋은 글

마무리

Jupyter Notebook 사용법: 셀 실행, 그래프 출력, 디버깅는 개념 자체보다 적용 상황과 한계를 함께 보는 것이 중요하다. 작은 예제로 동작을 확인하고, 실제 환경에서는 입력 조건과 예외 케이스를 따로 점검하는 습관을 두면 시행착오를 줄일 수 있다.

반응형
반응형

핵심 정리

Python 디스크립터는 클래스 속성으로 배치되어 인스턴스의 속성 읽기, 쓰기, 삭제 동작에 개입하는 객체입니다. 원문은 RevealAccess 예제로 이 흐름을 보여 주지만 Python 2 시절 표기와 설명을 포함하므로, 현재 Python 3 기준의 프로토콜과 구분을 먼저 확인하는 편이 안전합니다.

  • 현재 Python 공식 문서에서는 __get__(), __set__(), __delete__() 중 하나를 정의한 객체를 디스크립터로 설명합니다.
  • __set__() 또는 __delete__()를 정의하면 data descriptor이고, __get__()만 정의한 경우 non-data descriptor입니다. 원문의 둘 다 있어야 data descriptor라는 문장은 이 기준에 맞게 고쳐 읽어야 합니다.
  • RevealAccess 객체를 MyClass.x 같은 클래스 속성에 두면 m.x를 읽을 때 __get__()이, m.x에 값을 쓸 때 __set__()이 호출되어 로깅이나 검증 같은 추가 동작을 넣을 수 있습니다.
  • 원문의 print 'Retrieving' 형태는 Python 2 문법입니다. Python 3에서 실행하려면 print('Retrieving', self.name)처럼 함수 호출 형태로 바꾸며, 일반 클래스에서 object 상속을 명시할 필요도 없습니다.
  • property, 인스턴스 메서드의 바인딩, staticmethod, classmethod, super 같은 Python 기능을 이해할 때도 디스크립터 프로토콜이 핵심 배경이 됩니다.

먼저 아래 예제에서 x가 인스턴스 안의 평범한 값이 아니라 클래스에 놓인 RevealAccess 객체라는 점을 보고, 읽기와 쓰기 시 출력이 생기는 순서를 따라가면 됩니다.

이어서 볼 글

 

descriptor

> __get__, __set__, and __delete__. If any of those methods are defined for an object, it is said to be a descriptor.

> descriptors only work for new style objects and classes.

__get__, __set__ 둘다 가진넘을 data descriptor라고 하고,

__get__ 하나만 가진넘은 non-data descriptor라고 한다.


class RevealAccess(object):
    """A data descriptor that sets and returns values
       normally and prints a message logging their access.
    """

    def __init__(self, initval=None, name='var'):
        self.val = initval
        self.name = name

    def __get__(self, obj, objtype):
        print 'Retrieving', self.name
        return self.val

    def __set__(self, obj, val):
        print 'Updating' , self.name
        self.val = val

>>> class MyClass(object):
    x = RevealAccess(10, 'var "x"')
    y = 5

>>> m = MyClass()
>>> m.x
Retrieving var "x"
10
>>> m.x = 20
Updating var "x"
>>> m.x
Retrieving var "x"
20
>>> m.y
5

위 예제보면 별것도 아니네..

그냥 클래스 멥버variable접근할때 함수불리게 해서 추가동작 할 수 있는걸로 보인다.

(decorator랑도 비슷?)

근데 여러가지 파이선 기능 구현할때 이 기능을 사용해서 구현했다는거 같다.

> Descriptors are a powerful, general purpose protocol. They are the mechanism behind properties, methods, static methods, class methods, and super(). They are used used throughout Python itself to implement the new style classes introduced in version 2.2. Descriptors simplify the underlying C-code and offer a flexible set of new tools for everyday Python programs.

반응형
반응형

핵심 정리

약수는 정수 N을 나누어 나머지가 0이 되는 수입니다. 모든 수를 확인하는 완전 탐색은 이해하기 쉽지만 N까지 반복하고, 약수가 i와 N / i의 쌍으로 나타난다는 성질을 이용하면 제곱근까지만 확인해 탐색 범위를 줄일 수 있습니다.

  • Divisors 방식은 1부터 N까지 각 수로 나누어 보므로 시간복잡도는 O(N)입니다.
  • Divisors2는 i * i가 N 이하인 동안만 검사하고, 약수 i를 찾으면 짝인 N / i도 함께 추가하여 검사 횟수를 O(sqrt(N)) 범위로 줄입니다.
  • N이 완전제곱수이면 가운데 약수에서 i와 N / i가 같습니다. 원문처럼 set<int>에 넣으면 이 중복을 자동으로 제거하면서 정렬된 결과를 얻습니다.
  • 원문의 VI는 vector<int>와 같은 정수 벡터 별칭, FORE는 반복문 매크로로 쓰였다고 읽을 수 있습니다. 독립 실행 코드로 옮길 때에는 표준 컨테이너와 for 문으로 풀어 쓰면 됩니다.
  • 예를 들어 N이 12이면 1, 2, 3을 확인하면서 12, 6, 4를 함께 얻습니다. N이 16이면 4와 16 / 4가 같아지는 지점에서 중복 처리 이유가 드러납니다.

아래 첫 함수는 가장 단순한 기준 구현이고, 둘째 함수는 약수의 대칭성을 사용한 개선 구현입니다. 결과의 중복 제거와 정렬까지 필요한지에 따라 set 또는 vector와 후처리를 선택할 수 있습니다.

약수구하기

 

 


//Naive
VI Divisors(int n)
{
	VI v;
	FORE(i, 1, n)
	{
		if (n%i == 0) v.push_back(i);
	}
	return v;
}

//대칭성을 활용하면 sqrt 복잡도에 구할 수 있다.
VI Divisors2(int n)
{
	set<int> v;
	for (int i = 1; i*i <= n; i++)
	{
		if (n%i == 0) 
		{
			v.insert(i);
			v.insert(n/i);
		}
	}
	return VI(v.begin(), v.end());
}
반응형
반응형

핵심 정리

NumPy reshape는 배열의 데이터 값은 유지한 채 shape를 바꾸는 연산이고, np.isnan은 배열 원소마다 NaN 여부를 불리언 값으로 돌려주는 검사 함수입니다. 이 글의 그림은 같은 여섯 값을 2행 3열, 3행 2열, 1차원 배열, 열 벡터로 바꾸는 차이를 보여 줍니다.

  • reshape를 사용할 때에는 원소 총개수가 호환되어야 합니다. 예제의 여섯 원소는 (2, 3), (3, 2), (6,), (6, 1) 모양으로 바꿀 수 있습니다.
  • (6,)은 1차원 배열이고 (6, 1)은 행 여섯 개와 열 하나를 가진 2차원 배열이므로, 이후 연산이 기대하는 차원을 확인해야 합니다.
  • reshape(-1, 1)처럼 한 축에 -1을 지정하면 NumPy가 전체 원소 수와 나머지 축을 바탕으로 그 축의 크기를 계산합니다.
  • NaN 포함 여부를 확인할 때 np.nan in 배열 같은 멤버십 비교에 기대기보다 np.isnan(배열)로 원소별 마스크를 만들고, 필요하면 any 연산으로 하나라도 있는지 확인하는 흐름이 명확합니다.
  • 원문의 np.isnan(np.min(X)) 예제는 NaN이 섞인 집계 결과를 확인하는 메모이며, 개별 위치를 찾으려면 배열 자체에 np.isnan을 적용하는 편이 알맞습니다.

먼저 아래 이미지에서 reshape 전후 shape가 어떻게 달라지는지 확인하고, 이어지는 코드에서 NaN 비교가 일반 값 비교와 다르게 다뤄져야 하는 이유를 읽으면 됩니다.

이어서 볼 글

 

reshape

이 함수는 다음처럼 차원을 바꿀 때 사용함

2행 3열 NumPy 배열과 shape가 (2, 3)인 초기 상태
2행 3열 NumPy 배열과 shape가 (2, 3)인 초기 상태

원래는 2행 3열인 2차원 array 자료를

reshape로 같은 값을 3행 2열 배열로 바꾼 결과
reshape로 같은 값을 3행 2열 배열로 바꾼 결과

reshape으로 위처럼 3행 2열로 변경할 수 있다.

reshape(6)으로 배열을 1차원 형태로 바꾼 결과
reshape(6)으로 배열을 1차원 형태로 바꾼 결과

위 처럼 2차원을 1차원으로 줄일 수도 있고,

reshape(6, 1)로 열 벡터 형태를 만든 결과
reshape(6, 1)로 열 벡터 형태를 만든 결과

1차원같은 2차원으로 만들수도 있다(이런 형태가 Keras 쓰다보면 필요함)

더욱 좋은 사용법은 -1을 이용해서 일부값을 스킵하면 알아서 채워준다는 것

reshape(-1, 1)에서 행 크기를 자동 추론한 결과
reshape(-1, 1)에서 행 크기를 자동 추론한 결과

nan 체크

놀랍게도 아래 방법으로는 체크가 되지 않는 경우가 있음을 발견


>>> X[date][isin]
array([ nan,  nan,  nan,  nan,  nan,  nan])
>>> np.nan in X[date][isin]
False

여기에도 해당 내용이 있다.


>>> np.isnan(np.min(X))
True

위 처럼 하라는거네

반응형

+ Recent posts