반응형
반응형

1. EXPORT

  • 테이블의 데이터를 다른 형태 데이터로 추출하는 작업

1.1 문법

  • COPY 테이블명(칼럼1, 칼럼2,..) TO '경로' DELIMITER ',' CSV HEADER
    • COPY : 추출할 테이블과 컬럼들을 지정
    • TO : 추출할 경로를 지정(폴더가 미리 존재해야함)
    • DELIMITER : CSV 파일의 구분자 지정
    • CSV HEADER : HEADER 가 있으면 헤더 추가됨

1.2 예제

  • CATEGORY 테이블을 DB_CATEGORY.csv 파일로 출력
COPY CATEGORY(CATEGORY_ID, NAME, LAST_UPDATE)
TO 'D:\DB_CATEGORY.csv'
DELIMITER ','
CSV HEADER
;

2. IMPORT

  • 다른 데이터를 테이블에 넣는 작업

2.1 문법

  • COPY 테이블명(칼럼1, 칼럼2,..) FROM '경로' DELIMITER ',' CSV HEADER
    • COPY : 적재할 테이블과 컬럼들을 지정
    • FROM : 적재할 파일 경로를 지정(폴더가 미리 존재해야함)
    • DELIMITER : CSV 파일의 구분자 지정
    • CSV HEADER : HEADER 가 있으면 첫행을 헤더로 인식

2.2 예제

  • 데이터 적재를 할 테이블 생성
CREATE TABLE CATEGORY_IMPORT
(
CATEGORY_ID SERIAL NOT NULL
, "NAME" VARCHAR(25) NOT NULL
, LAST_UPDATE TIMESTAMP NOT NULL DEFAULT NOW()
, CONSTRAINT CATEGORY_IMPORT_PKEY PRIMARY KEY (CATEGORY_ID)
);
  • 데이터 적재
COPY CATEGORY_IMPORT(CATEGORY_ID, "NAME", LAST_UPDATE)
FROM 'D:\DB_CATEGORY.csv'
DELIMITER ','
CSV HEADER
;
SELECT * FROM CATEGORY_IMPORT;

category_id NAME last_update
0 1 Action 2006-02-15 09:46:27
1 2 Animation 2006-02-15 09:46:27
2 3 Children 2006-02-15 09:46:27
3 4 Classics 2006-02-15 09:46:27
4 5 Comedy 2006-02-15 09:46:27
5 6 Documentary 2006-02-15 09:46:27
6 7 Drama 2006-02-15 09:46:27
7 8 Family 2006-02-15 09:46:27
8 9 Foreign 2006-02-15 09:46:27
9 10 Games 2006-02-15 09:46:27
10 11 Horror 2006-02-15 09:46:27
11 12 Music 2006-02-15 09:46:27
12 13 New 2006-02-15 09:46:27
13 14 Sci-Fi 2006-02-15 09:46:27
14 15 Sports 2006-02-15 09:46:27
15 16 Travel 2006-02-15 09:46:27

참고

반응형

'데이터 분석 > SQL' 카테고리의 다른 글

[SQL] 7. 데이터 조작(INSERT, UPDATE, DELETE)  (0) 2021.05.23
[SQL] 6. 서브 쿼리(Sub Query)  (0) 2021.04.19
[SQL] 5. 집합 연산자  (0) 2021.04.19
[SQL] 4. 분석 함수  (0) 2021.04.05
[SQL] 3. 데이터 집계(Group by)  (0) 2021.04.01
반응형

1. INSERT문

  • 테이블 안에 데이터를 삽입하는 명령어

1.1 문법

  • INSERT INTO 테이블명 VALUES(v1,v2,...)
  • INSERT INTO 테이블명(칼럼명1, 칼럼명2,..) VALUES(v1, v2,...)

1.2 예제

  • 실습용 테이블 생성
CREATE TABLE LINK (
ID SERIAL PRIMARY KEY
, URL VARCHAR (255) NOT NULL
, NAME VARCHAR (255) NOT NULL
, DESCRIPTION VARCHAR (255)
, REL VARCHAR (50)
);

SELECT * FROM LINK;

id url name description rel
  • 1개의 데이터 행 추가
INSERT INTO LINK (URL, NAME)
VALUES ('http://naver.com','Naver');
COMMIT;

SELECT * FROM LINK;

id url name description rel
0 1 http://naver.com Naver None None
  • 작은따옴표를 데이터로 입력
INSERT INTO LINK(URL, NAME)
VALUES ('''http://naver.com''', '''Naver''');
COMMIT;

SELECT * FROM LINK;

id url name description rel
0 1 http://naver.com Naver None None
1 2 'http://naver.com' 'Naver' None None
  • 여러 개의 데이터 행 추가
INSERT INTO LINK(URL, NAME)
VALUES ('http://www.google.com','Google')
     , ('http://www.yahoo.com' ,'Yahoo')
     , ('http://www.bing.com'  ,'Bing')
;
COMMIT;

SELECT * FROM LINK;

id url name description rel
0 1 http://naver.com Naver None None
1 2 'http://naver.com' 'Naver' None None
2 3 http://www.google.com Google None None
3 4 http://www.yahoo.com Yahoo None None
4 5 http://www.bing.com Bing None None
  • 다른 테이블을 이용해 스키마만 있는 빈 껍데기 테이블 생성
CREATE TABLE LINK_TMP AS
SELECT * FROM LINK WHERE 0=1;
COMMIT

SELECT * FROM LINK_TMP

id url name description rel
  • 다른 테이블로부터 SELECT 하여 데이터 삽입
INSERT INTO LINK_TMP
SELECT * FROM LINK;
COMMIT;

SELECT * FROM LINK_TMP

id url name description rel
0 1 http://naver.com Naver None None
1 2 'http://naver.com' 'Naver' None None
2 3 http://www.google.com Google None None
3 4 http://www.yahoo.com Yahoo None None
4 5 http://www.bing.com Bing None None

2. UPDATE문

  • 테이블 안에 데이터를 편집할 때 사용하는 명령어

2.1 문법

  • UPDATE 테이블명 SET 컬럼명 = 값 WHERE 조건

2.2 예제

  • name 이 'Naver'인 데이터의 description을 name 컬럼값으로 수정
UPDATE LINK SET DESCRIPTION = NAME
WHERE NAME = 'Naver'
COMMIT;

SELECT * FROM LINK

id url name description rel
0 2 'http://naver.com' 'Naver' None None
1 3 http://www.google.com Google None None
2 4 http://www.yahoo.com Yahoo None None
3 5 http://www.bing.com Bing None None
4 1 http://naver.com Naver Naver None

3. UPDATE JOIN 문

  • 다른 테이블의 값을 참조하여 한 테이블의 값을 편집할 때 사용하는 명령어

3.1 문법

  • UPDATE 테이블1 A SET A.컬럼 = 값 FROM 테이블2 B WHERE A.컬럼 = B.컬럼

3.2 예제

  • 실습용 테이블 생성
-- PRODUCT_SEGMENT 테이블 생성 및 삽입
CREATE TABLE PRODUCT_SEGMENT
(
ID SERIAL PRIMARY KEY
, SEGMENT VARCHAR NOT NULL
, DISCOUNT NUMERIC (4, 2)
);

INSERT INTO PRODUCT_SEGMENT (SEGMENT, DISCOUNT)
VALUES
('Grand Luxury', 0.05)
, ('Luxury', 0.06)
, ('Mass', 0.1);
COMMIT;

-- PRODUCT 테이블 생성 및 삽입
CREATE TABLE PRODUCT(
ID SERIAL PRIMARY KEY
, NAME VARCHAR NOT NULL
, PRICE NUMERIC(10, 2)
, NET_PRICE NUMERIC(10, 2)
, SEGMENT_ID INT NOT NULL
, FOREIGN KEY(SEGMENT_ID)
REFERENCES PRODUCT_SEGMENT(ID)
);
NSERT INTO PRODUCT (NAME, PRICE, SEGMENT_ID)
VALUES
('K5', 804.89, 1)
, ('K7', 228.55, 3)
, ('K9', 366.45, 2)
, ('SONATA', 145.33, 3)
, ('SPARK', 551.77, 2)
, ('AVANTE', 261.58, 3)
, ('LOZTE', 519.62, 2)
, ('SANTAFE', 843.31, 1)
, ('TUSON', 254.18, 3)
, ('TRAX', 427.78, 2)
, ('ORANDO', 936.29, 1)
, ('RAY', 910.34, 1)
, ('MORNING', 208.33, 3)
, ('VERNA', 985.45, 1)
, ('K8', 841.26, 1)
, ('TICO', 896.38, 1)
, ('MATIZ', 575.74, 2)
, ('SPORTAGE', 530.64, 2)
, ('ACCENT', 892.43, 1)
, ('TOSCA', 161.71, 3);
COMMIT;
SELECT * FROM PRODUCT_SEGMENT;

id segment discount
0 1 Grand Luxury 0.05
1 2 Luxury 0.06
2 3 Mass 0.10
SELECT * FROM PRODUCT;

id name price net_price segment_id
0 1 K5 804.89 None 1
1 2 K7 228.55 None 3
2 3 K9 366.45 None 2
3 4 SONATA 145.33 None 3
4 5 SPARK 551.77 None 2
5 6 AVANTE 261.58 None 3
6 7 LOZTE 519.62 None 2
7 8 SANTAFE 843.31 None 1
8 9 TUSON 254.18 None 3
9 10 TRAX 427.78 None 2
10 11 ORANDO 936.29 None 1
11 12 RAY 910.34 None 1
12 13 MORNING 208.33 None 3
13 14 VERNA 985.45 None 1
14 15 K8 841.26 None 1
15 16 TICO 896.38 None 1
16 17 MATIZ 575.74 None 2
17 18 SPORTAGE 530.64 None 2
18 19 ACCENT 892.43 None 1
19 20 TOSCA 161.71 None 3
  • PRODUCT_SEGMENT의 값을 참조하여 NET_PRICE 계산
UPDATE PRODUCT A
SET NET_PRICE = A.PRICE - (A.PRICE * B.DISCOUNT)
FROM PRODUCT_SEGMENT B
WHERE A.SEGMENT_ID = B.ID;
COMMIT;
SELECT * FROM PRODUCT;

id name price net_price segment_id
0 1 K5 804.89 764.65 1
1 2 K7 228.55 205.70 3
2 3 K9 366.45 344.46 2
3 4 SONATA 145.33 130.80 3
4 5 SPARK 551.77 518.66 2
5 6 AVANTE 261.58 235.42 3
6 7 LOZTE 519.62 488.44 2
7 8 SANTAFE 843.31 801.14 1
8 9 TUSON 254.18 228.76 3
9 10 TRAX 427.78 402.11 2
10 11 ORANDO 936.29 889.48 1
11 12 RAY 910.34 864.82 1
12 13 MORNING 208.33 187.50 3
13 14 VERNA 985.45 936.18 1
14 15 K8 841.26 799.20 1
15 16 TICO 896.38 851.56 1
16 17 MATIZ 575.74 541.20 2
17 18 SPORTAGE 530.64 498.80 2
18 19 ACCENT 892.43 847.81 1
19 20 TOSCA 161.71 145.54 3

4. DELETE 문

  • 테이블의 특정 데이터를 삭제할 때 사용

4.1 문법

  • DELETE FROM 테이블 WHERE 조건

4.2 예제

  • LINK 테이블
SELECT * FROM LINK;

id url name description rel
0 2 'http://naver.com' 'Naver' None None
1 3 http://www.google.com Google None None
2 4 http://www.yahoo.com Yahoo None None
3 5 http://www.bing.com Bing None None
4 1 http://naver.com Naver Naver None
  • LINK_TMP 테이블
SELECT * FROM LINK_TMP;

id url name description rel
0 1 http://naver.com Naver None None
1 2 'http://naver.com' 'Naver' None None
2 3 http://www.google.com Google None None
3 4 http://www.yahoo.com Yahoo None None
4 5 http://www.bing.com Bing None None
  • LINK 테이블에서 ID가 5인 행 삭제
DELETE FROM LINK WHERE ID = 5;
COMMIT;
SELECT * FROM LINK;

id url name description rel
0 2 'http://naver.com' 'Naver' None None
1 3 http://www.google.com Google None None
2 4 http://www.yahoo.com Yahoo None None
3 1 http://naver.com Naver Naver None
  • 다른 테이블 값을 참조하여 삭제
DELETE FROM LINK_TMP A USING LINK B
WHERE A.ID = B.ID
COMMIT;
SELECT * FROM LINK_TMP;

id url name description rel
0 5 http://www.bing.com Bing None None

5. UPSERT 문

  • INSERT 시도 시에 조건에 따라 UPDATE를 할 수 있는 구문

5.1 문법

  • INSERT INTO 테이블명(컬럼) VALUES(값) ON CONFLICT(타켓컬럼) 액션
  • 액션 종류
    • DO NOTHING : 충돌 시 아무 것도 하지 말라
    • DO UPDATE SET ... : 충돌 시 업데이트 하라

5.2 예시

  • 실습 테이블 생성(NAME 컬럼에 UNIQUE 제약 조건 설정)
CREATE TABLE CUSTOMERS
(
CUSTOMER_ID SERIAL PRIMARY KEY
, NAME VARCHAR UNIQUE
, EMAIL VARCHAR NOT NULL
, ACTIVE BOOL NOT NULL DEFAULT TRUE
);

INSERT INTO CUSTOMERS (NAME, EMAIL)
VALUES
('IBM', 'contact@ibm.com'),
('Microsoft', 'contact@microsoft.com'),
('Intel', 'contact@intel.com');
COMMIT;

SELECT * FROM CUSTOMERS;

customer_id name email active
0 1 IBM contact@ibm.com True
1 2 Microsoft contact@microsoft.com True
2 3 Intel contact@intel.com True
  • 이미 있는 NAME 값을 추가 시 아무것도 하지 않음
INSERT INTO CUSTOMERS (NAME, EMAIL)
VALUES
(
'Microsoft', 'hotline@microsoft.com'
)
ON CONFLICT (NAME) DO NOTHING;
COMMIT;

customer_id name email active
0 1 IBM contact@ibm.com True
1 2 Microsoft contact@microsoft.com True
2 3 Intel contact@intel.com True
  • 이미 있는 NAME 값을 추가 시 email 컬럼에 내용 추가
    • EXCLUDED.EMAIL 은 위에서 INSERT 시도한 EMAIL을 가리킴
INSERT INTO CUSTOMERS (NAME, EMAIL)
VALUES ('Microsoft', 'hotline@microsoft.com')
ON CONFLICT (NAME) DO UPDATE
SET EMAIL = EXCLUDED.EMAIL || ';' || CUSTOMERS.EMAIL;

customer_id name email active
0 1 IBM contact@ibm.com True
1 3 Intel contact@intel.com True
2 2 Microsoft hotline@microsoft.com;contact@microsoft.com True

참고

반응형

'데이터 분석 > SQL' 카테고리의 다른 글

[SQL] 8. 데이터 EXPORT/IMPORT  (0) 2021.05.23
[SQL] 6. 서브 쿼리(Sub Query)  (0) 2021.04.19
[SQL] 5. 집합 연산자  (0) 2021.04.19
[SQL] 4. 분석 함수  (0) 2021.04.05
[SQL] 3. 데이터 집계(Group by)  (0) 2021.04.01
반응형

1. 아파치 하둡이란?

  • 빅데이터를 수집, 저장, 처리, 분석 할 수 있는 소프트웨어 프레임워크
  • 주요 특징
    • Ditributed : 수십만대의 컴퓨터에 자료 분산 저장 및 처리
    • Scalable : 용량이 증대되는 대로 컴퓨터 추가
    • Fault-tolerant : 하나 이상의 컴퓨터가 고장나도 시스템이 정상 동작
    • Open source : 공개 소프트웨어

2. hadoop을 왜 쓰는가?

  • 데이터 크기가 커져 가면서, 저장과 처리를 어떻게 할지에 대해 고민을 하게됨

2.1 전통적인 고성능 서버 방식의 한계

  • 더 많은 데이터를 처리하기 위해서는 더 빠른 Scale-up을 수행
    • scale-up : processor와 memory를 확장하여 해결
  • 하지만, 지속적으로 향상시키는데에는 한계가 존재함

2.2 분산 처리 시스템 방식 도입-1(MPI)

  • 하나의 작업을 처리하기 위해 여러 대의 컴퓨터를 사용
  • 더 많은 데이터를 처리하기 위해서는 더 많은 컴퓨터를 확장하여 해결
  • 분산 처리를 위해 MPI(Message Passing Interface) 방법을 사용
    • 컴퓨터 사이에 메시지를 전달하여 분산 처리를 수행함
    • 하지만 복잡하여 사용하기 어려움

2.3 분산 처리 시스템 방식 도입-2(GFS+MR , Haddop)

  • 구글에서 저성능 서버 여러 대에 데이터를 분선 저장/처리 하는 시스템 개발함
    • GFS(GoogleFile System) 라고 하는 파일 저장 관리 시스템을 개발
    • MR(MapReduce)라고 하는 분산 데이터 처리 방법을 개발
  • 하지만 Google에서 해당 기술을 Open하지 않음
  • Apache 에서 GFS와 MR을 참고하여 Hadoop이라고 하는 기술을 개발하여 open함

3. hadoop ecosystem

  • 데이터 수집
    • Sqoop : 정형데이터(관계형 데이터베이스등)에 있는 데이터를 가져 오는 프로그램
    • Flume : 비정형데이터(로그파일 등)에 있는 데이터를 가져오는 프로그램
  • 데이터 저장
    • HDFS(Haddop Distributed File System) : 데이터를 분산하여 저장하는 파일시스템
    • HBase : 컬럼기반 NoSQL 데이터베이스
  • 데이터 처리/분석
    • YARN/Map Reduce : 분산 데이터 처리
    • Pig : 스크리브 언어 기반 분석 도구
    • Hive : SQL기반 분석 도구
    • Mahout : 기계학습 알고리즘 기반 데이터 처리
  • 데이터 관리
    • Oozie : 빅데이터 처리 과정 관리
    • HCatalog : 빅데이터 메타 정보 관리
    • Zoo keeper : 빅데이터 서버 시스템 관리
  • Hadoop ecosystem 관리
    • Hue : 하둡의 프로그램들을 쉽게 실행시키는 동작하는 프로그램

참고

반응형
반응형

1. 컴퓨터에서 한글을 표현하는 방법

  • 완성형

    • '가' ,'닭' 등의 글자를 그대로 표현하는 방법
    • EX) '가' 의 경우 0xB0A1 값을 가짐
  • 조합형

    • '가' 를 'ㄱ' + 'ㅏ' 형태로 조합해서 표현하는 방법
    • 한글을 표현하는데 이상적이나 요즘은 거의 사용하지 않음
  • 확장 완성형

    • 위의 완성형에서 표시하지 못하는 '똠'과 같은 모든 한글을 표현할 수 있도록 범위를 확장한 형태
    • 확장된 문자열은 글자순으로 정렬되어 있지 않음
  • 유니코드

    • 전세계 언어들을 하나의 방법으로 표시하기 위한 방법
    • 일종의 완성형 형태이며, 정렬되어 있음

2. 한글을 표현하는 문자열 세트(Character set) 종류

  • 요약
charset이름 내용
EUC-KR - 완성형 표현방법을 사용한 방법

- 총 2350개 한글을 표현 가능

- 2Byte를 사용하여 한글 표현
CP949 - 확장 완성형 표현방법을 사용한 방법

- EUC-KR을 확장하여 모든 한글을 표현 가능

- 2Byte를 사용하여 한글 표현
UTF-8 - 유니코드를 이용하는 방법

- 모든 한글을 표현 가능

- 3Byte를 이용해 한글 표현

3. EUC-KR

  • KS 완성형 + 아스키 코드가 합쳐진 형태
    • KSX 1001로 정의된 완성형 표현방법을 사용
  • 아스키 코드(영어 포함)는 1Byte(00~7F)로 표현됨
  • 한글은 2Byte로 표현하며 각 Byte가 A1~FE 영역을 가짐
    • A1~FE 가 94가지를 가지므로 94 X 94 = 8,836 가지를 표현 가능
    • 한글에는 한글, 한자, 부호가 포함되어 있으므로 모든 한글에 코드를 부여할 수 없음
    • 자주 사용하는 한글 2350개만 코드로 할당하였으므로 한글은 2350개만 표현 가능
    • 문자표를 참조하면 해당 Hex값을 확인 가능
  • 한글 표현 범위(2350자)
    • 0xB0A1('가') ~ 0xC8FE('힝')
    • 상위 비트 범위 0xB0 ~ 0xC8 (25가지)
    • 하위 비트 범위 0xA1 ~ 0xFE (94가지)
    • 25 X 94 = 2350자
  • 자음, 모음 표현 범위
    • 자음 30자 : 0xA4A1 ~ 0xA4BE
    • 모음 21자 : 0xA4BF ~ 0xA4D3
    • 옛 한글 자모 : 0xA4D5 ~ 0xA4FE
  • 특수 문자
    • 상위 비트 범위 : 0xA1 ~ 0xAC
    • 하위 비트 범위 : 0xA1 ~ 0xFE(94가지)

4. CP949

  • 모든 한글을 표현하기 위해 EUC-KR을 확장한 형태로 EUC-KR과 호환이 가능하다.
    • EUC-KR -> CP949의 경우 모든 한글에 대해 깨짐없이 변환 가능
    • CP949 -> EUC-KR 의 경우 EUC-KR 코드표에 없는 문자(예:'똠')는 변환시 문자 깨짐 발생함
  • EUC-KR의 확장이므로 아래 내용은 동일함
    • 아스키 코드는 1Byte로 표현
    • 한글은 2Byte로 표현하며 각 Byte가 A1~FE 영역을 가짐
  • EUC-KR에 누락된 한글들을 표현하기 위해 아래 범위에 코드를 부여
    • (81-A0)(41-5A, 61-7A, 81-FE)
    • (A1-C5)(41-5A, 61-7A, 81-A0)
    • (C6) (41-52)

5. UTF-8

  • 유니코드로 표현하는 방법으로 모든 한글을 표현 가능하다.
    • U+AC00 ~ U+D7A3 범위를 가짐
    • 초성(19) X 중성(21) X 종성(27+1) = 총 11,172 개의 한글 표현 가능
    • 한글 음절 참고
  • 가변 크기로 1~4바이트 크기를 가짐
  • 한글의 경우 3바이트로 표현
    • 실제 2바이트(16비트)로 모든 한글 표현 가능하나 유니코드 설계상 3바이트로 인코딩함(아래 인코딩 참조)

5.1 UTF-8 인코딩 방법

  • UTF-8 코드 범위
코드 범위 크기 UTF-8 설명
000000-00007F 1Byte 0xxxxxxx 아스키 코드 표현
000080-0007FF 2Byte 110xxxxx

10xxxxxx
- 첫 바이트는 '1'로 표현

- 두 번째 바이트는 '10'으로 표현
000800-00FFFF 3Byte 1110xxxx

10xxxxxx

10xxxxxx
- 첫 바이트는 '1'로 표현

- 나머지 바이트는 '10'으로 표현
010000-10FFFF 4Byte 11110xxx

10xxxxxx

10xxxxxx

10xxxxxx
SMP 영역
  • 최상위비트(MSB)를 판단하여 아스키코드 인지 다른 문자인지 판단
    • 최상위비트(MSB) 가 0이면, 1Byte로 인코딩 후 아스키코드 문자 표현
  • 최상위비트(MSB)가 1이면 첫 번째 byte의 앞 n개 bit를 비교해 2~4byte로 인코딩
    • 최상위 비트 3개가 110 이면, 2Byte로 인코딩 후 해당 코드표에 있는 문자 표현
    • 최상위 비트 4개가 1110 이면, 3Byte로 인코딩 후 해당 코드표에 있는 문자 표현(한글이 여기 포함됨)
    • 최상위 비트 5개가 11110 이면, 4Byte로 인코딩 후 해당 코드표에 있는 문자 표현
    • 두번째~ 네번째 byte 앞 2bit는 10으로 고정됨
  • 한글 UTF-8 인코딩 예시
    • '위' : 0xC704 = 1100 0111 0000 0100
    • 위의 16비트를 4 + 6 + 6 으로 나누어 3Byte 의 고정영역을 제외한 부분에 넣음
    • 1100 011100 000100 => 3개 영역으로 분리
    • 11101100 10011100 10000100 => 고정영역 제외 부분에 넣음
    • 11101100 => 0xEC
    • 10011100 => 0x9C
    • 10000100 => 0x84
    • UTF-8 로 3바이트 (EC9C84) 로 인코딩됨
반응형
반응형

1. QGIS 파이썬 콘솔로 작업하기

  • QGIS에서 파이썬 콘솔 실행(CTRL + ALT + P)
    • 아래의 텍스트 편집기가 표시 되며 파이썬 코드 실행 가능

2. 레이어 로딩하기

  • 파이썬 콘솔 창에 아래 코드 입력
  • 2가지 방법이 있음(QgsProject, iface)

2.1 방법1

  • QgsProject 의 addMapLayers method 사용
link = QgsVectorLayer(r'D:\data\[2021-04-05]NODELINKDATA\MOCT_LINK.shp', 'mLink','ogr')
node = QgsVectorLayer(r'D:\data\[2021-04-05]NODELINKDATA\MOCT_NODE.shp', 'mNode','ogr')
QgsProject.instance().addMapLayers([link, node])

  • QgsVectorLayer : path 파일을 통해 Vector Layer 객체를 생성
    • path : 파일 경로 지정(메모리일 경우 별도 포맷으로 입력)
    • 레이어명칭 : 레이어 대표 명칭 입력
    • provider : 동작을 수행할 provider 입력
  • addMapLayers : vector Layer객체를 Map layer에 추가한다.

2.2 방법2

  • iface 사용
ilink = iface.addVectorLayer(r'D:\data\[2021-04-05]NODELINKDATA\MOCT_LINK.shp', 'ifaceLink','ogr')
inode = iface.addVectorLayer(r'D:\data\[2021-04-05]NODELINKDATA\MOCT_NODE.shp', 'ifaceNode','ogr')

3. 레이어 조회, 삭제

3.1 레이어 조회

  • QgsProject 클래스의 mapLayers method 사용
    • EX) 4개의 레이어 객체가 출력됨
QgsProject.instance().mapLayers()
{'ifaceLink_32ac8313_af37_4c95_a181_274d20739ec1': <QgsVectorLayer: 'ifaceLink MOCT_LINK' (ogr)>,
 'ifaceNode_848b785e_3b87_4741_96c5_d02330f04282': <QgsVectorLayer: 'ifaceNode MOCT_NODE' (ogr)>,
 'mLink_4286530d_ef44_4b31_9326_af0d07f501c2'    : <QgsVectorLayer: 'mLink' (ogr)>,
 'mNode_aee8efc1_f39c_4955_807d_a953a0cb3e6d'    : <QgsVectorLayer: 'mNode' (ogr)>}

3.2 레이어 삭제

  • QgsProjet 클래스의 removeMapLayer method 사용
    • 인자로 상기 결과의 id값을 직접 전달
    • 또는 layer명.id() 를 인자로 전달
# 1. id값을 직접 전달
QgsProject.instance().removeMapLayer('ifaceLink_32ac8313_af37_4c95_a181_274d20739ec1')

# 2. layer명.id() 를 인자로 전달
QgsProject.instance().removeMapLayer(node.id()))

# 3. 다시 레이어 조회
QgsProject.instance().mapLayers()
{'ifaceNode_848b785e_3b87_4741_96c5_d02330f04282': <QgsVectorLayer: 'ifaceNode MOCT_NODE' (ogr)>,
 'mLink_4286530d_ef44_4b31_9326_af0d07f501c2'    : <QgsVectorLayer: 'mLink' (ogr)>}

4. 레이어 속성

4.1 레이어 좌표계 확인

  • 좌표계 대표 명칭 확인
crs = link.crs()
crs.description()
'ITRF2000_Central_Belt_60'
  • 좌표계 WKT로 표현
crs.toWkt()
'PROJCS[
    "ITRF2000_Central_Belt_60"
    ,GEOGCS["ITRF2000"
        ,DATUM["International_Terrestrial_Reference_Frame_2000"
            ,SPHEROID["GRS 1980",6378137,298.257222101]
            ,AUTHORITY["EPSG","6656"]
        ]
        ,PRIMEM["Greenwich",0]
        ,UNIT["Degree",0.0174532925199433]
    ]
    ,PROJECTION["Transverse_Mercator"]
    ,PARAMETER["latitude_of_origin",38]
    ,PARAMETER["central_meridian",127]
    ,PARAMETER["scale_factor",1]
    ,PARAMETER["false_easting",200000]
    ,PARAMETER["false_northing",600000]
    ,UNIT["metre",1,AUTHORITY["EPSG","9001"]]
    ,AXIS["Easting",EAST]
    ,AXIS["Northing",NORTH]
]'

4.2 레이어 상자 경계 얻기

  • string 형태로 레이어 상자 경계 얻기
extent = link.extent()
extent.toString()
'101766.5375999962707283,67516.4931999971158803 : 546275.7760999957099557,665746.5176000001374632'
  • Polygon(WKT) 형태로 레이어 상자 경계 얻기
extent.asWktPolygon()
'POLYGON((101766.5375999962707283 67516.49319999711588025, 546275.77609999570995569 67516.49319999711588025, 546275.77609999570995569 665746.51760000013746321, 101766.5375999962707283 665746.51760000013746321, 101766.5375999962707283 67516.49319999711588025))'
  • 상하좌우 경계 얻기
extent.xMinimum()
extent.xMaximum()
extent.yMinimum()
extent.yMaximum()
101766.53759999627
546275.7760999957
67516.49319999712
665746.5176000001

4.3 레이어 개수 얻기

  • featureCount
link.featureCount()
528232

4.4 레이어의 특정 feature 얻기

  • 첫 번째 feature의 geometry 조회
item = link.getFeatures() # feature iterator 생성
feat = QgsFeature() # 빈 feature 생성
item.nextfeatrue(feat) # feat에 첫 번째 feature 값 할당
feat.geometry() # 첫번 째 feature의 geometry 조회
<QgsGeometry: MultiLineString ((245889.2084229375468567 602540.10316239262465388, 245884.52438196362345479 602550.70766398275736719, 245880.58459971970296465 602562.44166173494886607, 245877.37697640058468096 602577.55608172016218305, 245874.80402102915104479 602590.92314239405095577, 245870.08166344027267769 602608.65557601337786764, 245866.1486026662751101 602619.1390588756185025, 245861.72407481138361618 602627.99418399820569903, 245850.4775304970680736 602649.69330804911442101, 245843.77653209323761985 602663.28828775370493531, 245840.21593625328387134 602674.27399252017494291, 245836.27413596049882472 602686.38314351008739322, 245833.96002093932474963 602698.12587899703066796, 245831.74675705164554529 602714.37113853613846004, 245830.48617608763743192 602739.50042814784683287, 245829.72781690946430899 602764.25725230504758656, 245829.78834916753112338 602799.52310311701148748, 245829.1886519008257892 602818.02802740619517863, 245827.46483578640618362 602836.27679859660565853, 245825.86203727853...>
  • vector type 확인
feat.geometry().type()
1

4.5 필드 정보 조회

  • 속성 정보 개수 조회
feat.fields().count()
17
  • 특정 속성정보 이름/Type 조회
feat.fields()[2].name()
feat.fields()[2].typeName()
'T_NODE'
'String'
  • 속성값 조회
    • 속성 이름, 속성 번호로 조회 가능
feat['T_NODE']
feat[2]
'2630076901'
'2630076901'

4.6 반복적으로 속성 조회

  • 도로명칭이 '화악산로' 인 도로 조회
    • 개수가 많아 5개 만 찾고 for문 종료
idx = 0
for f in link.getFeatures():
    if f["ROAD_NAME"] == '화악산로':
        print("OK idx = ", idx)
        idx = idx+1
    if(idx == 5):
        break
OK idx =  0
OK idx =  1
OK idx =  2
OK idx =  3
OK idx =  4

5. 신규 레이어 만들기(Point 예제)

  • 메모리에 레이어 생성
theLayer=QgsVectorLayer('Point?crs=epsg:4326','SomePoints','memory')
  • 속성 필드 추가
    • ID 와 NAME Field 추가
theFeatures = theLayer.dataProvider() # Feature를 다루는 class 할당
theFeatures.addAttributes([QgsField("ID", QVariant.Int),QgsField("Name", QVariant.String)])
  • 레이어에 feature 추가 하기
p=QgsFeature()   # 빈 feature 생성
point = QgsPointXY(-106.3463, 34.9685) # 임시 Geometry 클래스 생성
p.setGeometry(QgsGeometry.fromPointXY(point)) # 임시 Geometry를 p feature에 set
p.setAttributes([123,"Paul"]) # 속성 정보를 p feature에 set
theFeatures.addFeatures([p]) # Features class에 p를 add
theLayer.updateExtents() # 범위를 업데이트
theLayer.updateFields() # 속성정보를 업데이트
QgsProject.instance().addMapLayers([theLayer]) # 레이어 로딩

6. PostGIS와의 연동(Polygon 예제)

  • Sample 데이터를 postgres sql에 저장하고 실습 진행

    • Sample을 위해 행정 경계 데이터를 여기 에서 다운
    • 해당 데이터의 좌표계를 EPSG4326으로 변경 후 postgresql에 저장
  • postgresql 서버에 연결하여 polygon 데이터 조회하기


# 1. postgresql 서버에 연결하여 polygon 데이터 조회하기
import psycopg2
connection = psycopg2.connect(database='geospatial', user='postgres', password='qkrtkddus!1')
cursor = connection.cursor()
cursor.execute("select *, ST_AsTexT(geom) from tl_scco_ctprvn")
c = cursor.fetchall()

# 2. QGIS 레이어 및 Feature 생성(속성 필드 추가)
sigungu = QgsVectorLayer('Polygon','Sigungu','memory')
sigunguFeatures = sigungu.dataProvider()
sigunguFeatures.addAttributes([QgsField("ID", QVariant.Int), QgsField("Name",QVariant.String)])

# 3. QGIS 레이어에 postgresql 에서 조회해온 데이터 삽입하기
for poly in c:
  g=QgsGeometry.fromWkt(poly[5])  # geometry 저장
  p=QgsFeature()      # 빈 feature 생성
  p.setGeometry(g)    # feature 에 geometry setting
  p.setAttributes([poly[1], str(poly[3])]) # feature 에 속성 setting
  sigunguFeatures.addFeatures([p]) # features 변수에 feature 추가
  sigungu.updateExtents() # 범위를 업데이트
  sigungu.updateFields() # 속성정보를 업데이트
  QgsProject.instance().addMapLayers([sigungu]) # 레이어 로딩

7. Feature 추가, 편집, 삭제, 조회

  • 앞선 2. 레이어 로딩하기에서 로딩한 Node 데이터로 예제 진행
  • 레어어에 가능한 작업 리스트 확인
node.dataProvider().capabilitiesString()
'객체 추가, 객체 삭제, 속성 값 변경, 속성 추가, 속성 삭제, 속성 이름 바꾸기, 공간 인덱스 생성, 속성 인덱스 생성, ID로 빠른 객체 접근, 도형 변경'

7.1 Feature 추가

  • 새로운 Node 1개 추가
feat = QgsFeature(node.fields())
feat.setAttribute('NODE_ID', 99999999999)
feat.setAttribute('NODE_TYPE', 1)
# 또는 위의 코드를 아래와 같이 한줄로 표현 가능
# feat.setAttributes([999999999999, 1 , ...속성값들])
feat.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(221689.09,462751.59)))
node.dataProvider().addFeatures([feat])
추가 전 추가 후

7.2 Feature 삭제

  • 차선이 1개인 링크 삭제
deleteList = []
for x in link.getFeatures():
  if x["LANES"] == 1:
    deleteList.append(x.id())
link.dataProvider().deleteFeatures(deleteList)
삭제 전 삭제 후

7.3 Feature 편집

  • '서울외곽순환고속도로' 링크를 '수도권제1순환고속도로'로 명칭 변경
for x in link.getFeatures():
  if x['ROAD_NAME'] == '서울외곽순환고속도로':
    link.dataProvider().changeAttributeValues({x.id():{7:'수도권제1순환고속도로'}})
변경 전 변경 후

7.4 Feature 선택(수식 이용)

  • 도로번호가 1이면서 도로명이 '경부고속도로인 링크 선택하기
link.selectByExpression("ROAD_NO=1 and ROAD_NAME='경부고속도로'")
변경 전 변경 후

8. Toolbox

8.1 Toolbox 사용하기

  • 사용 가능한 Toolbox 기능 리스트 확인하기
    • QgsApplication.processingRegistry().algorithms() : 사용 가능한 알고리즘 전체 객체 리스트
    • alg.provider().name() : 알고리즘 provider 이름
    • alg.name() : 알고리즘 이름
    • alg.displayName() : 알고리즘 표시 이름
from qgis import processing
for alg in QgsApplication.processingRegistry().algorithms():
  print("{}:{} --> {}".format(alg.provider().name(), alg.name(), alg.displayName()))
GDAL:aspect --> 경사 방향
GDAL:assignprojection --> 투영체 적용
GDAL:buffervectors --> 벡터 버퍼
GDAL:buildvirtualraster --> 가상 래스터 생성
GDAL:buildvirtualvector --> 가상 벡터 생성
GDAL:cliprasterbyextent --> 범위로 래스터 자르기
...
  • 알고리즘 이름으로 찾기
[x.id() for x in QgsApplication.processingRegistry().algorithms() if "buffer" in x.id()]
['gdal:buffervectors', 'gdal:onesidebuffer', 'grass7:r.buffer', 'grass7:r.buffer.lowmem', 'grass7:v.buffer', 'native:buffer', 'native:bufferbym', 'native:multiringconstantbuffer', 'native:singlesidedbuffer', 'native:taperedbuffer', 'native:wedgebuffers', 'qgis:variabledistancebuffer', 'saga:fixeddistancebuffer', 'saga:rasterbuffer', 'saga:rasterproximitybuffer', 'saga:thresholdrasterbuffer', 'saga:variabledistancebuffer']
  • 알고리즘 사용방식 확인
processing.algorithmHelp("native:buffer")
버퍼 (native:buffer)

이 알고리즘은 고정 또는 동적 거리를 사용해서 입력 레이어의 모든 객체에 대해 버퍼 영역을 계산합니다.

둥근 오프셋을 생성하는 경우 선분 파라미터가 사분원을 비슷하게그리는 데 사용할 라인 선분의 개수를 제어합니다.

선끝(end cap) 스타일 파라미터는 버퍼 내부에서 라인 끝부분을 어떻게 처리할지 제어합니다.

결합 스타일 파라미터는 오프셋이 라인의 모서리에 적용될 경우 결합 부위를 둥글게(round) 할지, 마이터(miter)로 할지, 비스듬하게(bevel) 할지 지정합니다.

마이터 제한 파라미터는 마이터 결합 스타일에만 적용할 수 있으며, 마이터 결합 부위를 생성하는 경우 사용할 오프셋 곡선으로부터의 최대 거리를 제어합니다.


----------------
Input parameters
----------------

INPUT: 입력 레이어

    Parameter type:    QgsProcessingParameterFeatureSource

    Accepted data types:
        - str: 레이어 ID
        - str: 레이어 이름
        - str: 레이어 원본
        - QgsProcessingFeatureSourceDefinition
        - QgsProperty
        - QgsVectorLayer

DISTANCE: 거리

    Parameter type:    QgsProcessingParameterDistance

    Accepted data types:
        - int
        - float
        - QgsProperty

SEGMENTS: 선분

    반올림한 오프셋을 생성하는 경우, 선분 파라미터가 사분원을 근사치로 계산하기 위해 사용할 라인 선분의 개수를 제어합니다.

    Parameter type:    QgsProcessingParameterNumber

    Accepted data types:
        - int
        - float
        - QgsProperty

END_CAP_STYLE: 선끝 스타일

    Parameter type:    QgsProcessingParameterEnum

    Available values:
        - 0: 둥글게
        - 1: 평평하게
        - 2: 정사각형

    Accepted data types:
        - int
        - str: int를 표현하는 문자열, 예. '1'
        - QgsProperty

JOIN_STYLE: 이음새 스타일

    Parameter type:    QgsProcessingParameterEnum

    Available values:
        - 0: 둥글게
        - 1: 마이터(miter)
        - 2: 비스듬하게(bevel)

    Accepted data types:
        - int
        - str: int를 표현하는 문자열, 예. '1'
        - QgsProperty

MITER_LIMIT: 마이터 제한

    Parameter type:    QgsProcessingParameterNumber

    Accepted data types:
        - int
        - float
        - QgsProperty

DISSOLVE: 결과물 디졸브

    Parameter type:    QgsProcessingParameterBoolean

    Accepted data types:
        - bool
        - int
        - str
        - QgsProperty

OUTPUT: 산출물

    Parameter type:    QgsProcessingParameterFeatureSink

    Accepted data types:
        - str: 대상 벡터 파일, 예. 'd:/test.shp'
        - str: 임시 메모리 레이어에 결과를 저장하는 'memory :'
        - str: 벡터 공급자 ID 접두사 및 대상 URI 사용, 예. PostGIS 테이블에 결과를 저장하는 'postgres:…'
        - QgsProcessingOutputLayerDefinition
        - QgsProperty

----------------
Outputs
----------------

OUTPUT:  <QgsProcessingOutputVectorLayer>
    산출물
  • 알고리즘 사용하기(buffer)
result = processing.run("native:buffer",{'INPUT':'mNode','DISTANCE':10,'SEGMENTS':5, 'END_CAP_STYLE':0,'JOIN_STYLE':0,'MITER_LIMIT':2, 'DISSOLVE':False,'OUTPUT':'memory:'})
QgsProject.instance().addMapLayer(result['OUTPUT'])

8.2 Toolbox 만들기

참고

  • 파이썬을 활용한 지리공간 분석 마스터하기
  • 예제는 국가표준노드링크로 진행
  • QGIS 파이썬 라이브러리는 여기 참고
반응형
반응형

1. 서브 쿼리란?

  • SQL 문 내에서 Main 쿼리가 아닌 하위에 존재하는 쿼리
  • 서브 쿼리를 활용해 다양한 결과 도출 가능

2. 서브 쿼리 종류

  • 인라인 뷰(Inline View)

    • From 절에 위치하여 하나의 Table 용도로 사용되는 서브 쿼리
  • 스칼라 서브쿼리(Scalar Sub Query)

    • 칼럼절에 위치하여 하나의 컬럼 용도로 사용되는 서브 쿼리
  • 중첩 서브쿼리(일반 서브쿼리)

    • where 절에 위치하여 하나의 변수 용도로 사용되는 서브쿼리
-- ㄱ) 인라인 뷰
SELECT *
FROM PRODUCT A,
    ( SELECT AVG(PRICE) AS AVG_PRICE FROM PRODUCT ) B
WHERE A.PRICE > B.AVG_PRICE;

-- ㄴ) 스칼라 서브 쿼리
SELECT *, ( SELECT AVG(PRICE) FROM PRODUCT) AS AVG_PRICE
FROM PRODUCT A
WHERE A.PRICE > A.AVG_PRICE

-- ㄷ) 중첩 서브 쿼리
SELECT *
FROM PRODUCT
WHERE PRICE > (SELECT AVG(RENTAL_RATE) FROM PRODUCT)

3. 서브 쿼리 연산자

  • 서브 쿼리 결과가 1건 이상일 때 사용하는 연산자
  • 종류
이름 내용
ANY 서브 쿼리 결과 중 하나라도 만족하면 조건 성립
ALL 서브 쿼리 결과의 모든 값이 만족해야 조건 성립
IN 서브 쿼리 결과에 포함되는지 확인
EXISTS 서브 쿼리 결과에 특정 집합이 존재하는지 확인

3.1 ANY 연산자

  • 서브 쿼리 결과 중 하나라도 만족하면 조건 성립
  • 예제 1)
    • 영화 분류별 최대 상영시간 집합 추출
    • 상영시간이 상기 집합 중 하나라도 크거나 같은 영화 출력
SELECT TITLE, LENGTH FROM FILM
WHERE LENGTH >= ANY
    ( SELECT DISTINCT MAX(LENGTH)
      FROM FILM A INNER JOIN FILM_CATEGORY B
      ON A.FILM_ID = B.FILM_ID
      GROUP BY B.CATEGORY_ID
     )

-- 서브 쿼리 결과 집합은
-- 178, 181, 183, 184, 185 이다.
-- LENGTH가 상기 집합 중 하나의 값 만이라도 크거나 같으면 참
-- 180의 경우 178보다 크므로 참
-- 170의 경우 아무 데이터도 크지 않으므로 거짓
  • 예제 2)
    • 영화 분류별 최대 상영시간 집합 추출
    • 상영시간이 상기 집합 중 하나라도 같은 영화 출력
    • = ANY의 경우 IN과 같다.
SELECT TITLE, LENGTH FROM FILM
WHERE LENGTH = ANY
    ( SELECT DISTINCT MAX(LENGTH)
      FROM FILM A INNER JOIN FILM_CATEGORY B
      ON A.FILM_ID = B.FILM_ID
      GROUP BY B.CATEGORY_ID
     )

-- 서브 쿼리 결과 집합은
-- 178, 181, 183, 184, 185 이다.
-- LENGTH가 상기 집합 중 하나의 값 만이라도 같으면 참
-- 178의 경우 178과 동일하므로 참
-- 179의 경우 같은 데이터가 없으므로 거짓

3.2 ALL 연산자

  • 서브 쿼리 결과의 모든 값이 만족해야 조건 성립
  • 예제 1)
    • 영화 분류별 최대 상영시간 집합 추출
    • 상영시간이 상기 집합의 모든 데이터 보다 크거나 같은 영화 출력
SELECT TITLE, LENGTH FROM FILM
WHERE LENGTH >= ALL
    ( SELECT DISTINCT MAX(LENGTH)
      FROM FILM A INNER JOIN FILM_CATEGORY B
      ON A.FILM_ID = B.FILM_ID
      GROUP BY B.CATEGORY_ID
     )

-- 서브 쿼리 결과 집합은
-- 178, 181, 183, 184, 185 이다.
-- LENGTH가 상기 집합의 모든 데이터보다 크거나 같으면 참
-- 185의 경우 모든 데이터 보다 크거나 같으므로 참
-- 180의 경우 178보다 크지만 181보다 작으므로 거짓

3.3 EXISTS 연산자

  • 서브 쿼리 결과에 특정 집합이 존재하는지 확인
  • 동작 중 조건에 만족하는 데이터 발견 시 동작을 멈추므로 속도 빠름
  • 예제 1)
    • 고객중에서 11불을 초과한 지불내역이 있는 고객 추출
SELECT FIRST_NAME, LAST_NAME
FROM CUSTOMER C
WHERE EXISTS (
    SELECT 1
    FROM PAYMENT P
    WHERE P.CUSTOMER_ID = C.CUSTOMER_ID
    AND P.AMOUNT > 11
    )
ORDER BY FIRST_NAME, LAST_NAME;

# 참고

반응형

'데이터 분석 > SQL' 카테고리의 다른 글

[SQL] 8. 데이터 EXPORT/IMPORT  (0) 2021.05.23
[SQL] 7. 데이터 조작(INSERT, UPDATE, DELETE)  (0) 2021.05.23
[SQL] 5. 집합 연산자  (0) 2021.04.19
[SQL] 4. 분석 함수  (0) 2021.04.05
[SQL] 3. 데이터 집계(Group by)  (0) 2021.04.01
반응형

1. 집합 연산자 종류

이름 기능
UNION 두 집합을 합친다.(중복 데이터 제거)
UNION ALL 두 집합을 합친다.(중복 데이터 모두 출력)
INTERSECT 두 집합 모두 가지는 데이터만 출력
EXCEPT 앞 집합에서 뒷 집합을 제외한 결과 출력
  • 예제 데이터
-- SALE1 Table
CREATE TABLE SALE1
(
NAME VARCHAR(50)
, AMOUNT NUMERIC(15,2)
);
INSERT INTO SALE1
VALUES
('Mike', 150)
, ('Jon', 132)
, ('Mary', 100)
;

SELECT * FROM SALE1;

name amount
0 Mike 150.00
1 Jon 132.00
2 Mary 100.00
-- SALE2 Table
CREATE TABLE SALE2
(
NAME VARCHAR(50)
, AMOUNT NUMERIC(15,2)
);
INSERT INTO SALE2
VALUES
('Mike', 120)
, ('Jon', 142)
, ('Mary', 100)
;

SELECT * FROM SALE2;

name amount
0 Mike 120.00
1 Jon 142.00
2 Mary 100.00

2. UNION

  • 두 집합을 합치며, 중복 데이터는 제거 된다.
  • 중복 데이터인 Mary는 중복 제거 후 1건만 출력됨
SELECT * FROM SALE1
UNION
SELECT * FROM SALE2

name amount
0 Jon 132.00
1 Mary 100.00
2 Mike 120.00
3 Jon 142.00
4 Mike 150.00

3.UNION ALL

  • 두 집합을 합치며, 중복 데이터도 모두 출력된다.
  • 중복 데이터인 Mary도 2건 모두 출력
SELECT * FROM SALE1
UNION ALL
SELECT * FROM SALE2

name amount
0 Mike 150.00
1 Jon 132.00
2 Mary 100.00
3 Mike 120.00
4 Jon 142.00
5 Mary 100.00

4.INTERSECT

  • 두 집합 모두 가지는 데이터만 출력한다.
  • 중복 데이터인 Mary만 출력
SELECT * FROM SALE1
INTERSECT
SELECT * FROM SALE2

name amount
0 Mary 100.00

5.EXCEPT

  • 앞 집합에서 뒷 집합을 제외한 모든 데이터를 출력
  • JON, MIKE, MARY에서 중복된 MARY만 제외 후 출력
SELECT * FROM SALE1
EXCEPT
SELECT * FROM SALE2

name amount
0 Jon 132.00
1 Mike 150.00

# 참고

반응형

'데이터 분석 > SQL' 카테고리의 다른 글

[SQL] 7. 데이터 조작(INSERT, UPDATE, DELETE)  (0) 2021.05.23
[SQL] 6. 서브 쿼리(Sub Query)  (0) 2021.04.19
[SQL] 4. 분석 함수  (0) 2021.04.05
[SQL] 3. 데이터 집계(Group by)  (0) 2021.04.01
[SQL] 2. 데이터 조인  (0) 2021.03.29
반응형

1. Rasterio로 래스터 데이터 읽고 쓰기

  • Rasterio로 파일 읽기
import rasterio
dataset = rasterio.open(r'Natural_Earth_quick_start\50m_raster\NE1_50M_SR_W\NE1_50M_SR_W.tif')
  • 밴드 수 확인
dataset.count
3
  • 열 수(width) 조회
dataset.width
10800
  • 높이(height) 조회
dataset.height
5400
  • 공간 경계(boundbox) 조회
dataset.bounds
BoundingBox(left=-179.99999999999997, bottom=-89.99999999998201, right=179.99999999996405, top=90.0)
  • CRS 조회
dataset.crs
CRS.from_epsg(4326)
  • 밴드1 데이터 조회
band1 = dataset.read(1)
  • 이미지 보기
%matplotlib inline
from matplotlib import pyplot
pyplot.imshow(dataset.read(1))
pyplot.show()

2. GDAL로 래스터 데이터 읽고 쓰기

2.1 터미널에서 GDAL 명령 수행하기

  • 터미널 명령어 이며, 상기 내용 처럼 !를 포함하면 JupyterNoteBook에서 명령 가능하다.
  • 지원되는 모든 파일 형식 조회
!gdalinfo --formats
Supported Formats:
  VRT -raster- (rw+v): Virtual Raster
...
  • 파일 정보 요약(CRS 포함)
!gdalinfo "Natural_Earth_quick_start\50m_raster\NE1_50M_SR_W\NE1_50M_SR_W.tif"
Driver: GTiff/GeoTIFF
Files: Natural_Earth_quick_start\50m_raster\NE1_50M_SR_W\NE1_50M_SR_W.tif
Size is 10800, 5400
Coordinate System is:
GEOGCRS["WGS 84",
    DATUM["World Geodetic System 1984",
        ELLIPSOID["WGS 84",6378137,298.257223563,
            LENGTHUNIT["metre",1]]],
    PRIMEM["Greenwich",0,
        ANGLEUNIT["degree",0.0174532925199433]],
    CS[ellipsoidal,2],
        AXIS["geodetic latitude (Lat)",north,
            ORDER[1],
            ANGLEUNIT["degree",0.0174532925199433]],
        AXIS["geodetic longitude (Lon)",east,
            ORDER[2],
            ANGLEUNIT["degree",0.0174532925199433]],
    USAGE[
        SCOPE["unknown"],
        AREA["World"],
        BBOX[-90,-180,90,180]],
    ID["EPSG",4326]]
Data axis to CRS axis mapping: 2,1
Origin = (-179.999999999999972,90.000000000000000)
Pixel Size = (0.033333333333330,-0.033333333333330)
Metadata:
  AREA_OR_POINT=Area
  TIFFTAG_DATETIME=2014:10:18 09:32:38
  TIFFTAG_RESOLUTIONUNIT=2 (pixels/inch)
  TIFFTAG_SOFTWARE=Adobe Photoshop CC 2014 (Macintosh)
  TIFFTAG_XRESOLUTION=342.85699
  TIFFTAG_YRESOLUTION=342.85699
Image Structure Metadata:
  INTERLEAVE=PIXEL
Corner Coordinates:
Upper Left  (-180.0000000,  90.0000000) (180d 0' 0.00"W, 90d 0' 0.00"N)
Lower Left  (-180.0000000, -90.0000000) (180d 0' 0.00"W, 90d 0' 0.00"S)
Upper Right ( 180.0000000,  90.0000000) (180d 0' 0.00"E, 90d 0' 0.00"N)
Lower Right ( 180.0000000, -90.0000000) (180d 0' 0.00"E, 90d 0' 0.00"S)
Center      (  -0.0000000,   0.0000000) (  0d 0' 0.00"W,  0d 0' 0.00"N)
Band 1 Block=10800x1 Type=Byte, ColorInterp=Red
Band 2 Block=10800x1 Type=Byte, ColorInterp=Green
Band 3 Block=10800x1 Type=Byte, ColorInterp=Blue
  • GeoTiff를 JPEG로 변환
!gdal_translate -of JPEG "Natural_Earth_quick_start\50m_raster\NE1_50M_SR_W\NE1_50M_SR_W.tif" NE1_50M_SR_W.jpg
Input file size is 10800, 5400
0...10...20...30...40...50...60...70...80...90...100 - done.
!gdalinfo gdal_sample_v1.2_no_extensions.gpkg
Driver: GPKG/GeoPackage
Files: gdal_sample_v1.2_no_extensions.gpkg
Size is 512, 512
Subdatasets:
  SUBDATASET_1_NAME=GPKG:gdal_sample_v1.2_no_extensions.gpkg:byte_png
  SUBDATASET_1_DESC=byte_png - byte_png
  SUBDATASET_2_NAME=GPKG:gdal_sample_v1.2_no_extensions.gpkg:byte_jpeg
  SUBDATASET_2_DESC=byte_jpeg - byte_jpeg
Corner Coordinates:
Upper Left  (    0.0,    0.0)
Lower Left  (    0.0,  512.0)
Upper Right (  512.0,    0.0)
Lower Right (  512.0,  512.0)
Center      (  256.0,  256.0)

2.2 GDAL 라이브러리 사용

2.2.1 GDAL 읽기/쓰기/투영 확인/변경

  • sample 데이터에서 New Mexico Color Shaded Relief 데이터 다운
  • 데이터 읽기
from osgeo import gdal
nmtif = gdal.Open(r'Data/nm_relief_color_tif/nm_relief_color.tif')
print(nmtif.GetMetadata())
{'AREA_OR_POINT': 'Area', 'TIFFTAG_DATETIME': '2002:12:18  8:10:06', 'TIFFTAG_RESOLUTIONUNIT': '2 (pixels/inch)', 'TIFFTAG_SOFTWARE': 'IMAGINE TIFF Support\nCopyright 1991 - 1999 by ERDAS, Inc. All Rights Reserved\n@(#)$RCSfile: etif.c $ $Revision: 1.9.3.3 $ $Date: 2002/07/29 15:51:11EDT $', 'TIFFTAG_XRESOLUTION': '96', 'TIFFTAG_YRESOLUTION': '96'}
  • 투영 정보 확인
nmtif.GetProjection()
'PROJCS["NAD83 / UTM zone 13N",GEOGCS["NAD83",DATUM["North_American_Datum_1983",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4269"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",-105],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","26913"]]'
  • 투영 변경 하기
from osgeo import osr
p = osr.SpatialReference()
p.ImportFromEPSG(26913)
nmtif.SetProjection(p.ExportToWkt())
  • 새 TIF 파일로 저장
geoTiffDriver = "GTiff"
driver=gdal.GetDriverByName(geoTiffDriver)
out = driver.CreateCopy('copy.tif', nmtif, strict = 0)

2.2.2 데이터 다루기

  • 밴드 개수 구하기
nmtif.RasterCount
3
  • 1번 밴드 데이터 보기
band = nmtif.GetRasterBand(1)
values = band.ReadAsArray()
values
array([[254, 255, 255, ..., 250, 249, 247],
       [255, 255, 255, ..., 251, 250, 249],
       [255, 255, 255, ..., 252, 250, 249],
       ...,
       [255, 255, 255, ..., 255, 255, 254],
       [255, 255, 255, ..., 254, 253, 253],
       [255, 255, 255, ..., 252, 251, 251]], dtype=uint8)
values[1100,1100]
216
  • 특정 픽셀 컬러값 구하기
one = nmtif.GetRasterBand(1).ReadAsArray()
two = nmtif.GetRasterBand(2).ReadAsArray()
three = nmtif.GetRasterBand(3).ReadAsArray()
print(str(one[1100,1100]) + "," + str(two[1100,1100]) + "," + str(three[1100,1100]))
216,189,157
  • 특정 band 평균, 표준편차 얻기
one = nmtif.GetRasterBand(1)
one.ComputeBandStats()
(225.05771967375847, 34.08382839593031)
  • 특정 band 최대/최소값 구하기
print("최대값 = ", str(one.GetMaximum()))
print("최소값 = ", str(one.GetMinimum()))
최대값 =  255.0
최소값 =  0.0
  • 특정 band의 description 확인/변경
print("변경 전 = ", str(one.GetDescription()))
one.SetDescription("The Red Band")
print("변경 후 = ", str(one.GetDescription()))
변경 전 =  Band_1
변경 후 =  The Red Band
  • Jupyter Notebook에서 래스터 파일 보기
import numpy as np
from matplotlib.pyplot import imshow
%matplotlib inline
data_array=nmtif.ReadAsArray()
x=np.array(data_array[0])
image = x.reshape(x.shape[0], x.shape[1])
imshow(image, cmap='gist_earth')

2.2.3 GDAL을 이용한 래스터 생성

  • Sample Data 생성
    • numpy array 이용
raster = np.array([[10,10,1,10,10,10,10],
                  [1,1,1,50,10,10,50],
                 [10,1,1,51,10,10,50],
                 [1,1,1,1,50,10,50]])
raster
array([[10, 10,  1, 10, 10, 10, 10],
       [ 1,  1,  1, 50, 10, 10, 50],
       [10,  1,  1, 51, 10, 10, 50],
       [ 1,  1,  1,  1, 50, 10, 50]])
  • 래스터 파일 속성 설정
# 좌하단 모서리 좌표 설정
coord=(-106,629773, 35.105389)

# 폭 , 높이 설정
w, h = 10, 10

# 파일명 설정
name = "new.tif"
  • 래스터 파일에 쓰기
# 1. driver 가져오기
d=gdal.GetDriverByName("GTiff")

# 2. file 설정
rows = raster.shape[0]
cols = raster.shape[1]
numOfBands = 1
output = d.Create(name, cols, rows, numOfBands, gdal.GDT_UInt16)
output.SetGeoTransform((coord[0], w, 0, coord[1], 0 ,h))

# 3. 데이터 쓰기
output.GetRasterBand(1).WriteArray(raster)

# 4. 좌표계 설정
outsr = osr.SpatialReference()
outsr.ImportFromEPSG(4326)
output.SetProjection(outsr.ExportToWkt())

# 5. 파일에 쓰기
output.FlushCache()
  • 결과 확인
data = output.ReadAsArray()
w,h = 4,7
image = data.reshape(w,h)
imshow(image, cmap='Blues')
data

array([[10, 10,  1, 10, 10, 10, 10],
       [ 1,  1,  1, 50, 10, 10, 50],
       [10,  1,  1, 51, 10, 10, 50],
       [ 1,  1,  1,  1, 50, 10, 50]], dtype=uint16)

# 참고

  • 파이썬을 활용한 지리공간 분석 마스터하기
반응형
반응형

1. 데이터 읽기

  • 벡터 데이터 읽기
    • read_file(*.shp) : shp파일 읽어서 geoDataFrame에 저장
import geopandas as gpd
df = gpd.read_file(r'data/MOCT_LINK.shp',encoding='CP949')
df.head()

LINK_ID F_NODE T_NODE LANES ROAD_RANK ROAD_TYPE ROAD_NO ROAD_NAME ROAD_USE MULTI_LINK CONNECT MAX_SPD REST_VEH REST_W REST_H LENGTH REMARK geometry
0 2630193301 2630076801 2630076901 1 106 000 391 화악산로 0 0 000 60 0 0.0 0 1410.192910 None LINESTRING (245889.208 602540.103, 245884.524 ...
1 2630193001 2630076801 2630076701 1 106 003 391 화악산로 0 0 000 60 0 0.0 0 12.137670 None LINESTRING (245881.843 602537.719, 245885.114 ...
2 2630193101 2630076701 2630076801 1 106 003 391 화악산로 0 0 000 60 0 0.0 0 12.326808 None LINESTRING (245893.460 602528.496, 245889.209 ...
3 2630192801 2630076701 2630076601 1 106 000 391 화악산로 0 0 000 60 0 0.0 0 364.089006 None LINESTRING (245885.688 602526.172, 245886.272 ...
4 2630192901 2630076601 2630076701 1 106 000 391 화악산로 0 0 000 60 0 0.0 0 373.389143 None LINESTRING (246066.042 602242.391, 246069.650 ...
  • Geometry 표시 하기
%matplotlib inline
df.plot(color='black')

2. geoDataFrame 구조 확인

  • type 확인
type(df)
geopandas.geodataframe.GeoDataFrame
  • row, column 크기 확인
df.shape
(1331, 18)
  • column명 확인
df.columns
Index(['LINK_ID', 'F_NODE', 'T_NODE', 'LANES', 'ROAD_RANK', 'ROAD_TYPE',
       'ROAD_NO', 'ROAD_NAME', 'ROAD_USE', 'MULTI_LINK', 'CONNECT', 'MAX_SPD',
       'REST_VEH', 'REST_W', 'REST_H', 'LENGTH', 'REMARK', 'geometry'],
      dtype='object')
  • Geometry type 확인
df.geom_type
0         LineString
1         LineString
2    MultiLineString
3         LineString
4         LineString
dtype: object

3. 좌표계 확인

  • 좌표계 확인
df.crs
<Projected CRS: PROJCS["ITRF2000_Central_Belt_60",GEOGCS["GCS_ITRF ...>
Name: ITRF2000_Central_Belt_60
Axis Info [cartesian]:
- [east]: Easting (metre)
- [north]: Northing (metre)
Area of Use:
- undefined
Coordinate Operation:
- name: unnamed
- method: Transverse Mercator
Datum: International Terrestrial Reference Frame 2000
- Ellipsoid: GRS 1980
- Prime Meridian: Greenwich
  • 좌표계 변경
merc = df.to_crs({'init':'epsg:4326'})
merc.plot(color='black')

4. 포맷 변환

  • GeoDataFrame을 json 포맷으로 변환
# 데이터가 커서 sample로 1개 데이터만 json으로 변환
df.head(1).to_json()
'{"type": "FeatureCollection", "features": [{"id": "0", "type": "Feature", "properties": {"CONNECT": "000", "F_NODE": "2630076801", "LANES": 1, "LENGTH": 1410.19291001225, "LINK_ID": "2630193301", "MAX_SPD": 60, "MULTI_LINK": "0", "REMARK": null, "REST_H": 0, "REST_VEH": "0", "REST_W": 0.0, "ROAD_NAME": "\\ud654\\uc545\\uc0b0\\ub85c", "ROAD_NO": "391", "ROAD_RANK": "106", "ROAD_TYPE": "000", "ROAD_USE": "0", "T_NODE": "2630076901"}, "geometry": {"type": "LineString", "coordinates": [[245889.20842293755, 602540.1031623926], [245884.52438196362, 602550.7076639828], [245880.5845997197, 602562.441661735], [245877.37697640058, 602577.5560817202], [245874.80402102915, 602590.923142394], [245870.08166344027, 602608.6555760134], [245866.14860266628, 602619.1390588756], [245861.72407481138, 602627.9941839982], [245850.47753049707, 602649.6933080491], [245843.77653209324, 602663.2882877537], [245840.21593625328, 602674.2739925202], [245836.2741359605, 602686.3831435101], [245833.96002093932, 602698.125878997], [245831.74675705165, 602714.3711385361], [245830.48617608764, 602739.5004281478], [245829.72781690946, 602764.257252305], [245829.78834916753, 602799.523103117], [245829.18865190083, 602818.0280274062], [245827.4648357864, 602836.2767985966], [245825.86203727854, 602855.2765506067], [245823.64944289793, 602871.396758187], [245821.52694263405, 602894.0203128068], [245820.4236764545, 602913.1478050507], [245821.58007512547, 602930.6617291515], [245823.60645547815, 602949.1807706261], [245825.40895076204, 602962.8214614922], [245826.09405003514, 602974.9554847644], [245825.65368618732, 602987.0834576795], [245823.97894215182, 602996.2034733664], [245820.42842643222, 603005.3134050232], [245811.20958754103, 603022.0212222983], [245803.40463366537, 603031.6085023026], [245795.35831640614, 603039.5687689325], [245779.41022924686, 603051.8634824678], [245761.20651050736, 603065.0214546616], [245744.9962197665, 603079.5657484786], [245711.8058337661, 603112.2767922183], [245676.3322525288, 603150.9782006346], [245664.11688441734, 603166.7945190094], [245654.27749311822, 603182.6236104805], [245646.6896994245, 603198.3397514643], [245641.49132830047, 603211.5676374831], [245635.8969615895, 603228.67010031], [245632.192484073, 603243.1565677221], [245627.70139361764, 603264.3917775303], [245625.5082893798, 603276.885489703], [245622.31073984868, 603290.1241318531], [245618.2163164351, 603307.3597129482], [245615.66553742788, 603316.6000712622], [245612.62396502416, 603324.0870205313], [245606.79428443874, 603338.4370064927], [245600.21765677864, 603352.1577013484], [245595.16584919338, 603361.384613071], [245585.18325133767, 603380.5894169775], [245577.72319553196, 603395.8060218558], [245572.39439199885, 603410.0336447023], [245567.3082955352, 603425.6381774854], [245563.35505705074, 603439.873195574], [245557.6094144114, 603461.851987991], [245552.1448012958, 603478.0797602631], [245546.8139796491, 603492.6825364484], [245543.12428970283, 603504.4178705714], [245537.91112339962, 603520.3968842088], [245527.91978245924, 603541.2273534045], [245501.14465575287, 603590.2300162113], [245479.78640583853, 603631.8835551282], [245454.11186099224, 603685.5191653903], [245430.8179966427, 603738.292187912], [245408.38805921804, 603793.195787896], [245399.2431610517, 603819.4081672801]]}}]}'
  • GeoDataFrame을 json 파일로 저장
    • driver : 출력 파일 포맷
df.to_file(driver='GeoJSON', filename='link.geojson')
  • 파일 출력 시 가능한 포맷
    • GeoPandas는 Fiona 라이브러리를 이용해 출력
    • 아래 명령을 통해 Fiona에서 지원하는 모든 driver 확인 가능
import fiona
fiona.supported_drivers

5. 데이터 다루기

  • 첫 번째 데이터 확인
df.loc[0]
LINK_ID                                              2180383101
F_NODE                                               2180132301
T_NODE                                               2180132201
LANES                                                         1
ROAD_RANK                                                   101
ROAD_TYPE                                                   000
ROAD_NO                                                      17
ROAD_NAME                                              서울문산고속도로
ROAD_USE                                                      0
MULTI_LINK                                                    0
CONNECT                                                     101
MAX_SPD                                                      50
REST_VEH                                                      5
REST_W                                                        0
REST_H                                                        0
LENGTH                                                  169.152
REMARK                                                     None
geometry      LINESTRING (310943.9252600061 4166093.43858687...
Name: 0, dtype: object
  • 특정 컬럼 데이터 조회
df['ROAD_NAME']
0       서울문산고속도로
1         개화동로8길
2         개화동로8길
3            당산길
4              -
          ...
1326    서울문산고속도로
1327    서울문산고속도로
1328    서울문산고속도로
1329    서울문산고속도로
1330    서울문산고속도로
Name: ROAD_NAME, Length: 1331, dtype: object
  • 컬럼 필터링
서울문산고속도로 = df[df['ROAD_NAME'] == '서울문산고속도로']
서울문산고속도로
  • Geometry 보기
서울문산고속도로.plot(figsize=(7,7))

6 공간 Join

  • 서울시에 포함되는 Link 찾기 예제
    • 행정경계는 여기에서 다운로드 가능
df2 = gpd.read_file(r'data/TL_SCCO_CTPRVN.shp')
df2.plot()

seoul_link = gpd.sjoin(df, seoul, op='within')

참고

반응형
반응형

1. Shapely로 Geometry 생성하기

  • Polygon 생성하기(튜플)
from shapely.geometry import Polygon
p1 = Polygon(((1,2), (5,3), (5,7), (1,9), (1,2)))
p1

p2 = Polygon(((6,6), (7,6), (10,4), (11,8), (6,6)))
p2

  • Point생성하기(좌표값)
from shapely.geometry import Point
point = Point(2.0, 2.0)
point

  • Line 생성하기
from shapely.geometry import LineString
line = LineString([(0,0), (10,10)])
line

  • Linear Ring 생성하기
from shapely.geometry.polygon import LinearRing
ring = LinearRing([(0,0), (3,3), (3,0)])
ring

  • MultiPoint 생성하기
from shapely.geometry import MultiPoint
points = MultiPoint([(0,0), (3,3)])
points

  • MultiLine 생성하기
from shapely.geometry import MultiLineString
coords = MultiLineString([((0,0), (1,1)),((-1,0), (1,0))])
coords

  • MultiPolygon 생성하기
from shapely.geometry import MultiPolygon
polygons = MultiPolygon([p1,p2])
polygons

2. Shapely 공간 함수


# 면적 구하기
print(p1.area)
# 경계 구하기
print(p1.bounds)
# 길이 구하기
print(p1.length)
# geometry Type 구하기
print(p1.geom_type)
22.0
(1.0, 2.0, 5.0, 9.0)
19.59524158061724
Polygon

3. Shapely로 JSON Geometry 읽기

  • Json 파일 생성 및 shape를 이용해 로딩
import json
from shapely.geometry import mapping, shape
jData = json.loads('{"type":"Polygon","coordinates":[[[1,1],[1,3],[3,3]]]}')
p = shape(jData)
p

  • geometry를 json형태로 변환
mapping(p)
{'type': 'Polygon', 'coordinates': (((1.0, 1.0), (1.0, 3.0), (3.0, 3.0), (1.0, 1.0)),)}

4 Fiona 데이터 읽기

  • shp 파일 정보 표출
print(len(c))
print(c.driver)
print(c.crs)
100
ESRI Shapefile
{'proj': 'tmerc', 'lat_0': 38, 'lon_0': 127, 'k': 1, 'x_0': 200000, 'y_0': 600000, 'ellps': 'GRS80', 'units': 'm', 'no_defs': True}
  • shp 파일 데이터 읽기
import fiona
c = fiona.open(r'data/node.shp')
rec = next(iter(c))
print('keys = ', rec.keys())
print('type = ', rec['type'])
print('prop = ', rec['properties'])
print('id   = ', rec['id'])
print('geom = ', rec['geometry'])
keys =  dict_keys(['type', 'id', 'properties', 'geometry'])
type =  Feature
prop =  OrderedDict([('NODE_ID', '1100025100'), ('NODE_TYPE', '101'), ('NODE_NAME', '하계5,6단지앞교차로'), ('TURN_P', '1'), ('REMARK', None)])
id   =  0
geom =  {'type': 'Point', 'coordinates': (205838.0880999937, 559449.3750999967)}

5 데이터 다루기

  • shape file 읽고 첫 번째 Feature 정보 가져오기
import fiona
with fiona.open(r'data/node.shp') as src:
    print(src[0])
{'type': 'Feature', 'id': '0', 'properties': OrderedDict([('NODE_ID', '1100025100'), ('NODE_TYPE', '101'), ('NODE_NAME', '하계5,6단지앞교차로'), ('TURN_P', '1'), ('REMARK', None)]), 'geometry': {'type': 'Point', 'coordinates': (205838.0880999937, 559449.3750999967)}}

참고

반응형

+ Recent posts

반응형