Python에서 외부 데이터 파일 읽기

파이썬에서 다양한 데이터 파일을 읽어오는 코드를 정리한 글로 추후 빠르게 참조하기 위한 목적으로 작성 되었습니다.

CSV 파일 읽기

import csv

rows = []
with open('../data/fileName.csv') as csvfile:
    csvreader = csv.reader(csvfile)
    next(csvreader, None)
    for row in csvreader:
        rows.append(row)

3번의 next 함수는 csv 파일의 첫줄에 있는 필드명을 건너뛰기 위함입니다. rows에 데이터가 저장됩니다.

JSON 파일 읽기

import json

with open('../data/fileName.json') as jsonfile:
    data = json.load(jsonfile)
    value_plainType = data["key1"]
    value_arrayType = data["key2"]
    value_dictionaryType = data["key3"]

    print(value_plainType)
    print(value_arrayType)
    print(value_dictionaryType["name"])

위의 fileName.json 파일의 내용이 다음과 같을때..

{
    "key1" : "string/numeric/bool",
    "key2" : [1, 2, 3, 4, 5],
    "key3" : { "name":"DoWise", "age": 12 }
}

출력 결과는 다음과 같습니다.

string/numeric/bool
[1, 2, 3, 4, 5]
DoWise

vi 편집기 명령 정리

이 글은 콘솔 환경에서 텍스트를 편집할 수 있는 vi 편집기 사용을 위해 요약한 글로 vi를 처음 접하는 분들은 다른 글을 참조하시기 바랍니다.

vi는 총 4가지 상태를 가지며 다음과 같은 상태 전환이 이루어집니다.

EX 모드

  • 변경된 내용 저장 w
  • 변경된 내용 저장하고 종료 wq
  • 변경된 내용 무시하고 종료 q!
  • 종료 q
  • 문자열 검색(예: boy) /boy
    • 다음 검색 문자열 n
    • 이전 검색 문자열 N
  • 문자열 변경(예: boy를 guy로 변경) %s/boy/guy/ig
  • 줄 번호 표시 set nu
  • 줄 번호 감추기 set nonu

명령 모드

  • 현재 커서 위치에서 편집 모드로 전환 i
  • 현재 커서 위치 줄의 첫문자 위치에서 편집 모드로 전환 I
  • 현재 커서의 바로 뒤에서 편집 모드로 전환 a
  • 현재 커서 위치 줄의 마지막 위치에서 편집 모드로 전환 A
  • 왼쪽으로 커서 위치 이동 h, ←
  • 오른쪽으로 커서 위치 이동 l, →
  • 위쪽으로 커서 위치 이동 k, ↑
  • 아래쪽으로 커서 위치 이동 j, ↓
  • 다음 단어 단위로 커서 이동 w
  • 이전 단어 단위로 커서 이동 b
  • 커서 위치 라인의 첫 문자로 이동 ^, 0
  • 커서 위치 라인의 끝 문자로 이동 $
  • 마지막 라인으로 이동 G
  • 100번째(1부터 시작) 라인으로 이동 100G
  • 편집된 내용 되돌리기 u
  • 커서 위치 한글자 삭제 x
  • 커서 위치를 포함해 세 글자 삭제 3x
  • 커서 앞의 글자 삭제 X
  • 커서 위치의 단어 단위로 삭제 dw
  • 커서 위치 줄 삭제 dd
  • 커서 위치의 줄을 포함해 세 줄 삭제 3dd
  • 커서 앞의 글자 삭제 X
  • 커서 위치에서 줄 끝 문자까지 삭제 D
  • 커서 위치의 줄을 버퍼에 복사 yy
  • 커서 위치의 줄을 포함해 세 줄을 버퍼에 복사 3yy
  • 버퍼에 복사된 문자열을 커서 위치에 붙여넣기 p
  • 버퍼에 복사된 문자열을 커서의 앞 위치에 붙여넣기 P
  • 한 글자만 수정 r
  • 커서 다음 위치에 빈줄 추가 o
  • 커서 이전 위치에 빈줄 추가 O
  • 커서 위치의 라인과 다음 라인을 한 라인으로 붙임 J

비주얼 모드

  • 글자 단위로 선택(명령모드에서 전환시) v
  • 라인 단위로 선택(명령모드에서 전환시) V
  • 블럭 단위로 선택(명령모드에서 전환시) ^v
  • 선택된 텍스트를 버퍼에 복사 y
  • 선택된 텍스트를 삭제 d, x

티베로(Tibero)의 Sequence 기능

Sequence는 국어로 표현하면 연속값 정도.. 하지만 시퀀스라고 이야기한다. 시퀀스는 DBMS 차원에서 유일한 정수 값이 필요할 때 사용된다. 티베로는 오라클의 SQL 구문과 매우 유사하다. 오라클을 이미 알고 있다면 쉽게 티베로도 사용할 수 있다. 그러므로 티베로의 Sequence와 관련된 내용은 모두 오라클의 그 것과 매우 유사하거나 동일하다.

먼저 시퀀스를 생성하는 구문이다.

CREATE SEQUENCE TEST_SEQ
MINVALUE 1 -- 기본값은 1
MAXVALUE 10 -- 기본값은 1E+28
NOCYCLE -- CYCLE로 지정되면 값이 최대값을 넘을 서면 다시 값은 최소값에서 시작됨, 기본값은 NOCYCLE로 값이 최대값을 넘어가면 에러 발생
NOCACHE;  -- 내부 메모리에 값을 캐시하는 것에 대한 설정으로 기본값은 NOCACHE이며 캐시하지 않은다는 의미

위의 구문 중 NOCACHE 옵션에 대한 부연 설명을 하면, 만약 아래처럼 CACHE 값을 지정했다고 하자.

CREATE SEQUENCE TEST_SEQ
CACHE 10;

시퀀스의 캐쉬 기능은 시퀀스 값을 더 빨리 생성하기 위해 원하는 개수만큼 미리 생성해 두게 된다. 위의 구문의 경우 미리 10개의 값을 생성해 두게 되고, NEXTVAL 함수를 통해 시퀀스 값을 생성할 때 미리 생성된 시퀀스 값을 빠르게 제공하게 된다. 문제는 미리 생성된 시퀀스 값들이 다 사용되지 못할지라도 다음의 시퀀스 값은 미리 생성된 값 다음 값이 사용된다는 점이다.

시퀀스가 생성되었다면, 시퀀스 값을 다음 구문으로 얻어올 수 있다.

SELECT TEST_SEQ.NEXTVAL FROM DUAL;

위의 구문을 통해 1이 얻어진다. 동일한 구문을 계속 실행하면 2, 3, 4, 5 등이 얻어지는 식이다. 여기서 DUAL 테이블은 임시 논리테이블로 어떤 함수의 사용법을 확인하기 위한 용도 등에 사용할 수 있다. 예를들어 함수의 사용을 확인하기 위해 테이블이 지정이 필요할때, 마땅이 지정할 테이블이 없을 경우 DAUL 테이블을 지정할 수 있다. (근데 왜 이름이 DAUL인지..)

NEXTVAL을 통해 매번 새로운 시퀀스 값을 얻는데, 새로운 값이 아닌 현재의 시퀀스 값을 확인하기 위한 구문은 다음과 같다.

SELECT TEST_SEQ.CURRVAL FROM DUAL;

시퀀스를 제거하는 구문은 다음과 같다.

DROP SEQUENCE TEST_SEQ;

마지막으로 생성된 시퀀스의 정보를 조회하는 구문은 다음과 같다.

SELECT * FROM ALL_SEQUENCES WHERE SEQUENCE_NAME = 'TEST_SEQ';

티베로에서 직접 위의 구문을 수행해 보면 다음과 같은 결과를 볼 수 있다. 환경에 따라 값이 달라질 수 있다.

GIS 엔진을 이용한 공간 통계 데이터 시각화 확장

통계 데이터를 공간 상에 시각화하기 위해 지리정보시스템(GIS)을 활용하는 것은 매우 효과적인 방법입니다. 흔히 주제도(Thematic Map)라고 하는 단계색상구분도(Choropleth Map), 차트맵(Chart Map), 밀도맵(Densit Map) 등이 가능하여, 각각의 예시는 아래 그림과 같습니다.

이외에도 다양한 종류의 주제도가 있고, 표현하고자 하는 관점에서 새로운 주제도가 계속 생겨날 것입니다. 이에 대해 GIS 엔진을 이용하여 새로운 주제도를 생성하는 내용을 API 관점에서 정리해 봅니다. GIS 엔진에 대한 정의는 다양하지만, 여기서 언급하는 GIS 엔진은 클라이언트 관점에서 지도를 시각화하고 지도를 조작하는 기능 등을 API로 제공하는 프로그램입니다. 이러한 GIS 엔진 중 저희 회사에서 개발한 FingerEyes-Xr을 이용해 글을 작성합니다.

FingerEyes-Xr은 통계 데이터를 공간 데이터로 시각화하기 위해 GraphicLayer라는 클래스를 이용합니다. 그래픽 레이어는 다양한 그래픽 요소로 구성되는데, 새로운 종류의 그래픽 요소를 정의함(즉, 클래스를 확장함)으로써 공간 통계 데이터를 원하는 형태로 표현할 수 있습니다. 먼저 시각화하고자 하는 통계 데이터를 살펴보면 다음과 같습니다.

위의 통계 데이터를 그래픽 요소의 확장을 통해 시각화한 결과는 다음과 같습니다.

각 지역구 별로 코로나 확진자 수를 표현하고 있으며, 코로나 발생자가 많은 지역구은 빨간색으로, 적은 지역구는 초록색으로 표시하고 있습니다. 이제 위의 공간 통계 지도를 생성하기 위한 GIS 엔진의 API를 정리해 보겠습니다.

새로운 그래픽 요소를 추가하기 위해서는 GraphicRow를 부모 클래스로 하여 파생 클래스와 ShapeData를 부모 클래스로 하는 파생 클래스를 만들어 줍니다. GraphcRow의 파생 클래스는 통계 데이터가 어떻게 지도 상에 그려지는가를 정의하며, ShapeData의 파생 클래스는 그려지기 위해서 가져야할 데이터를 정의합니다. 앞서 본 통계 지도의 모습이 손톱 모양의 주제도라는 관점에서 각각의 파생 클래스를 NailNumberGraphicRow와 NailNumberShapeData라고 하겠습니다.

먼저 NailNumberGraphicRow 클래스의 코드에서 중요한 부분을 언급하면 다음과 같습니다.

NailNumberGraphicRow = Xr.Class({
    extend: Xr.data.GraphicRow,

    construct: function (id, /* NailNumberShapeData */ graphicData) {
        Xr.data.GraphicRow.call(this, id, graphicData.clone());

        // 그래픽 요소를 화면상에 시각화 하기 위해 필요한 심벌 정의
        // NailNumberGraphicRow 클래스에서는 PenSymbol 객체 2개, BrushSymbol 객체 2개, FontSymbol 객체 2개를 사용했음
    },

    methods: {
        MBR: function (/* CoordMapper */ coordMapper, /* SVG Element */ container) {
            // 그래픽 요소가 공간 상에 차지하는 MBR을 정의해서 반환
        },

        /* SVG Element */ appendSVG: function (/* CoordMapper */ coordMapper, /* SVG Element */ container) {
            // coordMapper는 지도 좌표를 화면 좌표로, 화면좌표를 지도 좌표로 변환하는 기능을 제공함
            // 표현되는 모습에 따라 SVG 자식 요소를 생성하여 SVG container에 추가 함
            // 자식 요소가 여러 개라면 g 요소를 부모로 하고, 이 g 요소를 반환함
        }
    }
});

GraphicRow의 파생 클래스는 최소한 MBR과 appendSVG 함수를 구현해야 합니다. 물론, 그래픽 요소의 편집을 위해서는 더 많은 함수와 인터페이스를 구현해야 하지만, 단순히 표현만을 위한다면 이 2개의 함수의 구현만으로도 충분합니다. 다음은 NailNumberShapeData 클래스의 코드입니다. 역시 중요한 부분만을 언급하면 다음과 같습니다.

Xr.data.NailNumberShapeData = Xr.Class({
    extend: Xr.data.ShapeData,

    construct: function (/* { pos: [x, y], 
                              outbox_size: [width, height], inbox_size: [width, height], 
                              title: '..', value: 0, title_offset_y: 0, value_offset_y: 0 } */ arg) {
        Xr.data.ShapeData.call(this);

        this._data = arg;
        this._mbr = new Xr.MBR();
    },

    methods: {
        /* ShapeData */ clone: function () {
            let arg = {};
            for (k in this._data) {
                arg[k] = this._data[k];
            }

            let newThing = new Xr.data.NailNumberShapeData(arg);
            newThing._mbr.copyFrom(this._mbr);

            return newThing;
        },

        data: function () {
            return this._data;
        },

        MBR: function () {
            return this._mbr;
        },

        /* PointD */ representativePoint: function () {
            // 그래픽 요소의 대표 좌표을 지정합니다. 
            // 대부분의 경우 MBR의 중심점이 대표 좌표입니다.
            return new Xr.PointD(this._mbr.centerX(), this._mbr.centerY());
        },

        /* int */ type: function () {
            return "NailNumberShapeData";
        },
    }
});

생성자에서 그래픽 요소로써 표현하는데 필요한 데이터들을 매개변수로 받습니다. 세부적인 API의 설명은 피하고 꼭 중요한 부분만을 언급하여 간단이 설명했지만, 공간 데이터의 시각화에 대해 원하는 어떠한 방법이라도 위의 방법을 통해 지원이 가능합니다.

NexGen의 GeoAI 기능, 영상판독

GeoAI는 공간정보과학(Geospatial Science; Spatial Data Science)과 인공지능(Artificial Intelligence)의 합성어이며, 공간 빅데이터(Spatial Big Data)로부터 유의미한 정보를 도출하기 위해 인공지능 기술(A.I.: Machine Learning, Deep Learning)과 고성능 컴퓨터를 활용하는 분야입니다. GeoAI에는 여러가지 기능이 있는데, NexGen에서 영상판독 GeoAI 기능을 아래의 동영상 시연으로 소개합니다.

NexGen에서 GeoAI 서비스를 실행하기 위한 개략적인 시스템 구성도는 다음과 같습니다.

NexGen은 GIS를 활용한 업무에 특화된 기능을 제공하는 솔루션으로 커스터마이징이 가능하도록 개발되었습니다. TTA 1등급 인증을 받은 GIS 미들웨어인 GeoService-Xr과 오픈소스인 클라이언트 지도 엔진인 FingerEyes-Xr을 사용하여 개발되었습니다. NexGen에 대한 더 많은 내용은 아래의 글을 참고하시기 바랍니다.

웹 GIS 솔루션, NexGen 소개

신경망 학습을 위해서는 학습 데이터가 필요한데, 학습 데이터 구축은 직접 개발한 레이블링 툴을 이용하였습니다. GIS에 특화된 학습 데이터를 빠르게 구축할 수 있으며, 신경망 학습을 위한 형식으로 Export할 수 있는 기능을 제공합니다. 보다 자세한 내용은 아래의 글을 참고하시기 바랍니다.

GeoAI Labeling Tool 소개

학습 데이터는 데모 수준으로 구축했으며, 구축 수는 건물은 약 만개, 비닐하우스는 약 오천개 정도 구축하여 학습했습니다. 매우 소량이며, 실제 업무에 사용하기 위한 영상판독을 위해서는 더욱 많은 학습 데이터를 구축해야 하며, 앞서 언급한 레이블링 툴을 이용하여 빠르고 정확한 학습 DB 구축이 가능합니다.