데이터 크기가 작다면 Python이나 R로 데이터를 로딩해서 직접 동일 간격 구간별 집계를 한다든지, 변수별 히스토그램이나 박스 그래프, 막대그래프를 그릴 수 있을 것입니다. 하지만 데이터 크기가 로컬 컴퓨터의 메모리 한계를 벗어날 정도로 크다면 그때는 DB에서 SQL로 집계를 한 후, 집계 결과만을 Python이나 R로 가져와서 시각화를 하는 방법을 생각해볼 수 있습니다. 

이번 포스팅에서는 

(1) Greenplum DB, PostgreSQL DB의 width_bucket() SQL 함수를 사용하여 동일 간격 범위별로 관측치 개수를 세어보고, 

(2) Python에서 width_bucket() SQL Query를 재사용하기 쉽게 사용자 정의 함수(user defined function)을 정의하여, 

(3) Python으로 DB connect하여 GPDB에서 집계한 결과로 막대 그래프 그리는 방법

을 소개하겠습니다. 

먼저, 예제로 사용할 간단한 houses (세금, 화장실 개수, 욕실 개수, 가격, 크기) 데이터를 DBeaver나 PGadmin IV 등의 DB tool을 사용해서 테이블을 생성하고 insert into 해보겠습니다. 

DROP TABLE IF EXISTS houses;

CREATE TABLE houses (id INT, tax INT, bedroom INT, bath FLOAT, price INT,

            size INT, lot INT);

INSERT INTO houses VALUES

  (1 ,  590 ,       2 ,    1 ,  50000 ,  770 , 22100),

  (2 , 1050 ,       3 ,    2 ,  85000 , 1410 , 12000),

  (3 ,   20 ,       3 ,    1 ,  22500 , 1060 ,  3500),

  (4 ,  870 ,       2 ,    2 ,  90000 , 1300 , 17500),

  (5 , 1320 ,       3 ,    2 , 133000 , 1500 , 30000),

  (6 , 1350 ,       2 ,    1 ,  90500 ,  820 , 25700),

  (7 , 2790 ,       3 ,  2.5 , 260000 , 2130 , 25000),

  (8 ,  680 ,       2 ,    1 , 142500 , 1170 , 22000),

  (9 , 1840 ,       3 ,    2 , 160000 , 1500 , 19000),

 (10 , 3680 ,       4 ,    2 , 240000 , 2790 , 20000),

 (11 , 1660 ,       3 ,    1 ,  87000 , 1030 , 17500),

 (12 , 1620 ,       3 ,    2 , 118600 , 1250 , 20000),

 (13 , 3100 ,       3 ,    2 , 140000 , 1760 , 38000),

 (14 , 2070 ,       2 ,    3 , 148000 , 1550 , 14000),

 (15 ,  650 ,       3 ,  1.5 ,  65000 , 1450 , 12000);


SELECT * FROM houses;



1. Greenplum DB, PostgreSQL DB의 width_bucket() SQL 함수를 사용하여 
    동일 간격 범위별로 관측치 개수를 세기


houses 테이블에서 가격(price) 변수의 최소값은 $22,500, 평균은 $122,140, 최대값은 $260,000 이군요. 

SELECT 

min(price) AS min_val,  

avg(price) AS mean,

max(price) AS max_val

FROM houses


위에서는 SQL문의 min(), avg(), max() 함수를 써서 이들 통계량을 구했는데요, 경우에 따라서는 동일 간격의 범위/ 구간별로 관측치가 몇 개 있는지를 구해보고 싶은 경우가 있습니다. (<- 히스토그램으로 시각화를 하죠)  SQL 문으로 하려면 width_bucket() 함수를 사용하면 case when 문을 길게 쓰지 않고도 간편하게 '동일 간격 범위의 bucket 별로 관측치를 집계'할 수 있습니다. 

houses 테이블의 price 칼럼에 대해 5개의 동일 간격(즉, 4개의 cutting line을 사용)의 bucket별로 관측치를 세어(count) 보겠습니다. width_bucket(변수, 시작 값, 끝 값, cutting line 개수) 의 순서로 arguments를 넣어주면 되며, 이렇게 만든 bucket 별로 count(*) 하고, GROUP BY bucket 으로 그룹별 묶어주면 됩니다. 

SELECT 

width_bucket(price, 22500, 260000, 4) AS bucket, 

count(*) AS cnt

FROM houses

GROUP BY bucket

ORDER BY bucket;


그런데, 위의 집계 결과를 보면 각 bucket의 구간이 어떻게 되는지 표만 봐서는 알 수 없어서 좀 갑갑한 면이 있습니다. 그래서 이번에는 각 bucket의 구간의 시작(from_val)과 끝(to_val)의 값을 같이 볼 수 있도록 해보겠습니다. 그리고 width_bucket(변수, 시작 값, 끝 값, cutting line 개수) 에서 '시작 값(starting point)'과 '끝 값(ending point)'을 수작업으로 직접 입력해주는 것이 아니라 해당 변수의 최소값과 최대값을 min(), max() 함수로 구해서 자동으로 입력해줄 수 있도록 with clause SQL문을 사용해서 짜보겠습니다. 

WITH stats AS (

SELECT 

min(price) AS min_val

max(price) AS max_val

FROM houses

), bucket_tbl AS (

SELECT 

width_bucket(price, min_val, max_val, 4) AS bucket, 

count(*) AS cnt

FROM houses, stats

GROUP BY bucket

ORDER BY bucket

)

SELECT 

bucket, 

min_val + (bucket-1)*min_val AS from_val, 

min_val + bucket*min_val AS to_val, 

cnt

FROM stats, bucket_tbl;



처음보다 훨씬 보기에 좋아졌습니다. 그렇지요?! 

여기까지 짜보았으니 이제 슬슬 더 욕심이 나기 시작합니다. DB에서 SQL로 bucket 별 관측치 개수를 집계할 결과를 Python이나 R로 가져와서 시각화를 해보면 더 가독성이 좋아질텐데....., 위의 SQL문을 사용자 정의 함수로 만들어서 table이름, 변수이름, bucket 개수 입력값만 바꾸어주면 알아서 집계를 해주면 더 편할텐데.... 하는 욕심 말이지요. 

그래서, Python으로 Greenplum 이나 PoesgreSQL DB에 connect하여 위의 width_bucket() SQL문을 사용자 정의 함수로 만들고, DB에서 집계한 결과를 pandas의 DataFrame.plot.bar() 함수로 시각화해보겠습니다. 



2. Python에서 width_bucket() SQL Query를 재사용하기 쉽게
    사용자 정의 함수(user defined function)을 정의


여기서부터는 Jupyter Notebook이나 Spyder 와 같은 Python IDE에서 진행하면 됩니다. (저는 Jupyter Notebook을 사용하였습니다)

아래 Python 코드는 psycopg2 라이브러리를 사용해서 Greenplum DB 혹은 PostgreSQL DB에 접속하고, Query문을 받아서 실행시킨 후에, 그 결과를 pandas DataFrame으로 반환하는 사용자 정의 함수 read_sql() 함수를 정의한 것입니다. 


import pandas as pd

import matplotlib as plt

%matplotlib inline


# UDF for GPDB connection and Querying, Save to pandas DataFrame

def read_sql(query):

     import pandas as pd

     import psycopg2 as pg


    # DB Connection (put it with yours)

     conn = pg.connect(host='localhost', 

                       port='5432', 

                       dbname='postgres', 

                       user='postgres', 

                       password='postgres')

     # Get a DataFrame

     result = pd.read_sql(query, conn)

     conn.close()

     return result 





위에서 정의한 read_sql() 사용자 정의함수를 사용해서 5개 bucket 별로 관측치 개수를 집계한 SQL query문을 날려보겠습니다. SQL query문은 따옴표 3개 (""" sql query syntax """) 안에 써주면 됩니다. read_sql() 사용자 정의 함수가 잘 작동하는군요. 

 


 query = """

    WITH stats AS (

        SELECT 

            min(price) AS min_val, 

            max(price) AS max_val

        FROM houses

    ), bucket_tbl AS (

        SELECT 

        width_bucket(price, min_val, max_val, 4) AS bucket, 

        count(*) AS cnt

    FROM houses, stats

    GROUP BY bucket

    ORDER BY bucket

    )

    SELECT

        'price' AS column,

        bucket, 

        min_val + (bucket-1)*min_val AS range_low, 

        min_val + bucket*min_val AS range_high, 

        cnt

    FROM stats, bucket_tbl;

"""


rng_bucket = read_sql(query)

rng_bucket

columnbucketrange_lowrange_highcnt
0price122500450003
1price245000675007
2price367500900003
3price4900001125001
4price51125001350001




이제 위의 구슬들을 잘 꿰어서 진주 목걸이를 만들 차례가 되었습니다. Python의 format() 문을 접목하여 동일 간격 bucket 별로 관측치 개수를 집계하는 SQL query 문의 테이블 이름(tbl_nm), 변수 이름(var_nm), bucket 개수(bucket_num) 의 3개 인자를 받는 Python 사용자 정의 함수 rng_bucket(tbl_nm, var_nm, bucket_num)를 만들어보겠습니다. 


def rng_bucket(tbl_nm, var_nm, bucket_num=10):

    

    query = """

    WITH stats AS (

        SELECT 

            min({var_nm}) AS min_val, 

            max({var_nm}) AS max_val

        FROM {tbl_nm}

    ), bucket_tbl AS (

        SELECT 

        width_bucket({var_nm}, min_val, max_val, ({bucket_num}-1)) AS bucket, 

        count(*) AS cnt

    FROM {tbl_nm}, stats

    GROUP BY bucket

    ORDER BY bucket

    )

    SELECT 

        '{var_nm}' AS column,

        bucket, 

        min_val + (bucket-1)*min_val AS range_low, 

        min_val + bucket*min_val AS range_high, 

        cnt

    FROM stats, bucket_tbl

    ORDER BY bucket

    """.format(tbl_nm = tbl_nm, 

              var_nm = var_nm, 

              bucket_num = bucket_num)

    

    rng_bucket = read_sql(query)

    

    return rng_bucket;

 



목걸이로 다 꿰었으니 이제 rng_bucket() 사용자 정의 함수에 'price' 변수에 대해 bucket 개수를 5개, 10개로 넣어서 실행시켜 보고, 변수 이름을 'price' 대신 'tax'를 넣어서도 실행시켜 보겠습니다. 


rng_bucket('houses', 'price', 5)

columnbucketrange_lowrange_highcnt
0price122500450003
1price245000675007
2price367500900003
3price4900001125001
4price51125001350001

 

rng_bucket('houses', 'price', 10)

columnbucketrange_lowrange_highcnt
0price122500450001
1price245000675002
2price367500900004
3price4900001125001
4price51125001350004
5price61350001575001
6price92025002250001
7price102250002475001


rng_bucket('houses', 'tax', 5)

columnbucketrange_lowrange_highcnt
0tax120405
1tax240606
2tax360801
3tax4801002
4tax51001201


잘 동작하는군요! ^^


 3. Python으로 DB connect하여 GPDB에서 집계한 결과로 막대 그래프 그리기

마지막으로, pandas DataFrame으로 반환받은 세금(tax) 변수의 5개 bucket 별 집계 결과를 pandas 막대그래프(bar graph)로 그려보겠습니다. 


tax_bucket = rng_bucket('houses', 'price', 5)

ax = tax_bucket.plot.bar(x='bucket', y='cnt', rot=0)



요약하자면, 데이터 사이즈가 수백 테라바이트, 수 페타바이트급이면 Greenplum, PostgreSQL DB에서 집계하시구요, 결과는 Python이나 R로 시각화해서 보세요. 자주 쓰는 코드라면 사용자 정의 함수를 만들어놓고 재사용하시구요. 


많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. :-)


728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 Greenplum DB, Postgresql 에서 테이블을 생성한 후에 SQL로 데이터 전처리하는 몇 가지 방법을 소개하겠습니다. 

예제로 사용할 간단한 고객 정보 테이블을 생성하고, 행 번호, 고객번호, 이름, 나이, 성별, 지역, 등록일 값을 입력해보겠습니다. 


DROP TABLE IF EXISTS public.cust;

CREATE TABLE public.cust (

seq_num integer

, cust_id text not null

, name text not null

, age integer

, gender text

, region text

, regist_date date

);


INSERT INTO public.cust VALUES 

(1, 'A001', 'choi', 25, 'M', 'seoul', '2018-01-25'), 

(2, 'A002', 'kang', 30, 'F', 'Busan', '2019-02-08'), 

(3, 'A003', 'lee', 29, NULL, 'seoul', '2018-05-30'), 

(4, 'B001', 'kim', 35, 'F', 'seoul', '2018-12-22'), 

(5, 'B002', 'sung', 34, 'M', 'busan', '2019-02-19'),

(6, 'B003', 'park', NULL, NULL, 'SEOUL', '2019-03-15');


SELECT * FROM public.cust ORDER BY seq_num;



위의 테이블에서 

(1) 고객ID(cust_id) 문자열의 첫 번째 문자열을 가져다가 group 칼럼 만들기
    : SUBSTRING(cust_id, 1, 1) AS group

(2) group별로 seq_num 순서에 따라 행 번호 부여하기
    : ROW_NUMBER() OVER(PARTITION BY SUBSTRING(cust_id, 1, 1) ORDER BY seq_num) AS grp_num

(3) 나이(age) 결측값을 전체 평균 값으로 채우기 
    : COALESCE(age, AVG(age) OVER())::INTEGER AS age

(4) 성별(gender) 결측값을 "Unknown" 값으로 채우기 
    : COALESCE(gender, 'Unknown') AS gender

(5) 지역(region) 대문자를 소문자로 바꾸기 
    : LOWER(region) AS region

(6) 이름(name)이 'choi', 'park', 'lee', 'kim'은 그대로 두고, 그 외는 'others'로 바꾸어서 name_2 칼럼 만들기
    : CASE WHEN name IN ('choi', 'park', 'lee', 'kim') THEN name ELSE 'others' END AS name_2

-- substring of id's first character
-- insert row number
-- fill missing value of 'age' with average
-- fill missing value of 'gender' with 'Unknown'
-- convert upper letter into lower letter
-- if name IN ('choi', 'park', 'lee', 'kim') then name, else 'other'


DROP TABLE IF EXISTS public.cust_preprocessed CASCADE;

CREATE TABLE public.cust_preprocessed AS 

(

SELECT 

seq_num, 

cust_id, 

SUBSTRING(cust_id, 1, 1) AS group, 

ROW_NUMBER() OVER(PARTITION BY SUBSTRING(cust_id, 1, 1) ORDER BY seq_num) AS grp_num, 

COALESCE("age", AVG(age) OVER())::INTEGER AS "age", 

COALESCE(gender, 'Unknown') AS gender,

LOWER(region) AS region, 

name, 

CASE WHEN name IN ('choi', 'park', 'lee', 'kim') THEN name

ELSE 'others' END AS name_2, 

regist_date

FROM public.cust

ORDER BY cust_id

) DISTRIBUTED RANDOMLY;

SELECT * FROM public.cust_preprocessed ORDER BY seq_num;



다음으로 날짜 형식의 데이터에서 년(year), 월(month), 일(day), 현재 날짜(now), 입력 날짜로 부터 현재 날짜까지의 소요 일(day until now)을 계산해보겠습니다. 

(7) 등록 날짜에서 년(year) 정보 추출
  : EXTRACT (YEAR FROM regist_date)::int AS year

(8) 등록 날짜에서 월(month) 정보 추출
  : EXTRACT (MONTH FROM regist_date)::int AS month

(9) 등록 날짜에서 일(day) 정보 추출
  : EXTRACT (DAY FROM regist_date)::int AS day

(10) 현재 날짜 자동 입력
  : now()::DATE

(11) 이전 등록 날짜에서 현재까지의 소요 일 계산
  : AGE(regist_date) AS time_from_regist

 -- extract year, month, day from regist_date

DROP TABLE IF EXISTS public.cust_date CASCADE;

CREATE TABLE public.cust_date AS 

(

SELECT *, 

EXTRACT (YEAR FROM regist_date)::int AS year, 

EXTRACT (MONTH FROM regist_date)::int AS month, 

EXTRACT (DAY FROM regist_date)::int AS day, 

now()::DATE,

AGE(regist_date) AS time_from_regist

FROM public.cust_preprocessed

ORDER BY cust_id

) DISTRIBUTED RANDOMLY;

SELECT 

seq_num, regist_date, year, month, day, 

now, time_from_regist 

FROM public.cust_date 

ORDER BY seq_num;




많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. :-)


728x90
반응형
Posted by Rfriend
,

Greemplum DB로 데이터 분석을 하려고 할때 처음에 하는 일이 분석에 필요한 데이터를 Greenplum DB에 schema, table 생성하고 데이터를 table에 upload하는 입니다. 이번 포스팅에서는 외부의 데이터를 Greenplum Database Table에 업로드하는 5가지 방법을 소개하겠습니다. 

 

[ Greenplum DB에 외부 데이터를 upload하는 5가지 방법 ]

1. CREATE EXTERNAL TABLE 후 => CREATE TABLE

2. COPY table_name FROM directory DELIMITER

3. INSERT INTO VALUES ()

4. DB tool인 DBeaver Import Wizard (or pgAdmin IV)

5. Python pandas DataFrame.to_sql() 함수 사용

 

예제로 사용할 데이터는 UC Irvine Machine Learning Repository 에 있는 abalone 데이터셋입니다. 
( * source: http://archive.ics.uci.edu/ml/machine-learning-databases/abalone/abalone.data )

전복(abalone)의 성별, 길이, 반지름, 높이, 전체 무게, 내장을 뺀 후의 무게, 내장 무게, 껍질 무게, 고리 (+1.5를 하면 나이가 됨) 변수로 구성된 데이터셋입니다. Toy project로 나이 예측이나 성장정도 분류 문제에 종종 등장하곤 하는 데이터셋입니다. 

Attribute information:

   Given is the attribute name, attribute type, the measurement unit and a
   brief description.  The number of rings is the value to predict: either
   as a continuous value or as a classification problem.

	Name		Data Type	Meas.	Description
	----		---------	-----	-----------
	Sex		nominal			M, F, and I (infant)
	Length		continuous	mm	Longest shell measurement
	Diameter	continuous	mm	perpendicular to length
	Height		continuous	mm	with meat in shell
	Whole weight	continuous	grams	whole abalone
	Shucked weight	continuous	grams	weight of meat
	Viscera weight	continuous	grams	gut weight (after bleeding)
	Shell weight	continuous	grams	after being dried
	Rings		integer			+1.5 gives the age in years

   Statistics for numeric domains:

		Length	Diam	Height	Whole	Shucked	Viscera	Shell	Rings
	Min	0.075	0.055	0.000	0.002	0.001	0.001	0.002	    1
	Max	0.815	0.650	1.130	2.826	1.488	0.760	1.005	   29
	Mean	0.524	0.408	0.140	0.829	0.359	0.181	0.239	9.934
	SD	0.120	0.099	0.042	0.490	0.222	0.110	0.139	3.224 

Correl 0.557 0.575 0.557 0.540 0.421 0.504 0.628 1.0 

 

 

 

  1. CREATE EXTERNAL TABLE => CREATE TABLE

먼저 web 상에 올라가 있는 데이터를 url을 이용하여 external table로 만들고, 그 다음에 create table을 해서 Greenplum DB에 넣는 방법부터 소개하겠습니다. web에 있는 데이터 불러올 때나 하둡에 있는 데이터를 GPDB에 올릴 때는 이 방법에 제일 편리한거 같습니다. 

 

-- (1) Create an external web table

DROP EXTERNAL TABLE IF EXISTS public.abalone_external;
CREATE EXTERNAL WEB TABLE public.abalone_external(
  sex text 
  , length float8
  , diameter float8
  , height float8
  , whole_weight float8
  , shucked_weight float8
  , viscera_weight float8
  , shell_weight float8
  , rings integer -- target variable to predict
) location('http://archive.ics.uci.edu/ml/machine-learning-databases/abalone/abalone.data') 
format 'CSV' 
(null as '?');


--Create a table at Greenplum Database from an external table
DROP TABLE IF EXISTS public.abalone;
CREATE TABLE public.abalone AS
SELECT * FROM public.abalone_external
DISTRIBUTED BY (sex);

SELECT * FROM public.abalone LIMIT 10;

 

 

  2. COPY table_name FROM directory DELIMITER

두번째 방법은 데이터를 csv나 text 파일로 다운로드를 한 후에 => psql로 \COPY 문을 사용해서 Greenplum DB에 데이터를 업로드하는 방법입니다. 만약 회사 보안 상 외부 website url에서 external table로 가져올 수 없는 경우에 유용하게 사용할 수 있는 방법입니다. 파일 다운로드 한 경로에 가서 pwd 로 경로 확인한 후에 FROM 뒤에 데이터를 가져올 경로를 입력하시면 됩니다. 

 

-- (2) COPY

DROP TABLE IF EXISTS public.abalone;
CREATE TABLE public.abalone(
  sex text 
  , length float8
  , diameter float8
  , height float8
  , whole_weight float8
  , shucked_weight float8
  , viscera_weight float8
  , shell_weight float8
  , rings integer
) DISTRIBUTED BY (sex);


COPY public.abalone 
(sex, length, diameter, height, whole_weight, shucked_weight, 
viscera_weight, shell_weight, rings) 
FROM '/Users/ihongdon/Downloads/abalone.data.txt' DELIMITER ',' CSV;

 

 

Encodnig 을 설정하려면 아래의 예처럼 COPY 구문의 'ENCODING' 매개변수에 원하는 encoding 방법을 설정해주면 됩니다.

 

COPY public.abalone 
(sex, length, diameter, height, whole_weight, shucked_weight, 
viscera_weight, shell_weight, rings) 

FROM '/Users/ihongdon/Downloads/abalone.data.txt'
(DELIMITER ',', FORMAT CSV, ENCODING 'UTF8');

 

 

 

 

  3. INSERT INTO VALUES ()

입력해야 할 데이터 개수가 몇 개 안되는 경우, 혹은 기존 table에 소수의 데이터를 추가하는 경우에 간단하게 사용할 수 있는 방법이 insert into values() 입니다. tutorial 만들거나 교육용 샘플 데이터 만들 때 주로 사용하곤 하는 방법입니다. (반면, 데이터 개수가 많아지면 아무래도 사용하기에 좀 꺼려지는 방법입니다. -_-;)

create table에서 만든 칼럼과 동일한 순서로 데이터를 삽입할 때는 칼럼 이름을 생략해도 됩니다. 

 

-- (3)INSERT INTO VALUES()

DROP TABLE IF EXISTS public.abalone;
CREATE TABLE public.abalone(
sex text 
, length float8
, diameter float8
, height float8
, whole_weight float8
, shucked_weight float8
, viscera_weight float8
, shell_weight float8
, rings integer
) DISTRIBUTED BY (sex);


INSERT INTO public.abalone 
(sex, length, diameter, height, whole_weight, shucked_weight, viscera_weight, shell_weight, rings) 
VALUES 
('M',0.455,0.365,0.095,0.514,0.2245,0.101,0.15,15), 
('M',0.35,0.265,0.09,0.2255,0.0995,0.0485,0.07,7), 
('F',0.53,0.42,0.135,0.677,0.2565,0.1415,0.21,9), 
('M',0.44,0.365,0.125,0.516,0.2155,0.114,0.155,10), 
('I',0.33,0.255,0.08,0.205,0.0895,0.0395,0.055,7), 
('I',0.425,0.3,0.095,0.3515,0.141,0.0775,0.12,8), 
('F',0.53,0.415,0.15,0.7775,0.237,0.1415,0.33,20), 
('F',0.545,0.425,0.125,0.768,0.294,0.1495,0.26,16); 

 

 

 

  4. DB tool인 DBeaver Import Wizard 사용

 

csv나 text 파일로 다운로드 해놓은 데이터셋이 있는 경우, DB tool인 DBeaver나 pgAdmin IV의 Import Wizard를 사용하는 방법도 매우 편리합니다. 

 

 

-- (4) DBeaver tool's Import Wizard

DROP TABLE IF EXISTS public.abalone;

CREATE TABLE public.abalone(

sex text 

, "length" float8

, "diameter" float8

, "height" float8

, whole_weight float8

, shucked_weight float8

, viscera_weight float8

, shell_weight float8

, rings integer

) DISTRIBUTED BY (sex);

 

 

(1) DBeaver tool의 좌측 Database Navigator > DB > Schema > Tables > abalone 테이블에 '마우스 오른쪽' 클릭 > 'Import Data' 선택

 

(2) Data Transfer 창에서 'CSV' (Import from CSV file(s)) 선택

 

3. Input files 의 Source name 선택 > 탐색기 창이 나타나면 데이터셋이 저장되어 있는 경로로 가서 데이터셋 선택 > Open 단추 클릭 > Next 단추 클릭

 

4. Data Transfer: Preview data import 에서 데이터셋이 맞게 들어가 있는건지 미리보기로 확인

 

5. Data Transfer: Settings 화면 > Next 단추 클릭

 

6. Data Transfer: Confirm 창에서 최종 확인 후, 맞으면 'Finish' 단추 클릭

 

7. Data Transfer: Data transfer completed (소요 시간, 초)

 

 

 

 

  5. Python pandas DataFrame.to_sql() 함수 사용

 

파일 사이즈가 분석 환경의 메모리 한계 내에서 감당할만한 수준인 경우, Python pandas의 read_csv() 함수로 데이터를 읽어들여서 DataFrame으로 만든 다음에, pandas의 to_sql() 함수를 사용하여 Greenplum DB에 pandas DataFrame을 insert할 수 있습니다. 저는 분석할 때 대부분의 경우 Python이나 R을 GPDB와 연동(connect)에서 사용하는데요, Python이나 R의 분석결과를 다시 GPDB에 집어넣을 때 사용하는 방법입니다. 

(Greenplum Database에 Python 연동하는 방법은 https://rfriend.tistory.com/251 , https://rfriend.tistory.com/379 를 참고하세요)

 

# Importing data from website using pandas read_csv() function
abalone_data_url = "https://archive.ics.uci.edu/ml/machine-learning-databases/abalone/abalone.data"
abalone_columns = ( 'sex', 'length', 'diameter', 'height', 'whole_weight', 'shucked_weight', 'viscera_weight', 'shell_weight', 'rings')
df_abalone = pd.read_csv(abalone_data_url, names=abalone_columns)

df_abalone.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 4177 entries, 
0 to 4176 Data columns (total 9 columns): 
sex 4177 non-null object 
length 4177 non-null float64 
diameter 4177 non-null float64 
height 4177 non-null float64 
whole_weight 4177 non-null float64 
shucked_weight 4177 non-null float64 
viscera_weight 4177 non-null float64 
shell_weight 4177 non-null float64 
rings 4177 non-null int64 
dtypes: float64(7), int64(1), object(1) 
memory usage: 293.8+ KB



# export to Greenplum DB using pandas df.to_sql() function
# postgresql://Username:Password@Host:Port/Database
conn = "postgresql://gpadmin:changeme@localhost:5432/demo"

df_abalone.to_sql(
	'abalone', 
	conn, schema='public', 
    if_exists='replace', 
    index=True, 
    index_label='id', 
    chunksize=10000)
    

 

많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~

'를 꾹 눌러주세요. 

 

 

728x90
반응형
Posted by Rfriend
,

CNN(Convolutional Neural Network)으로 이미지 분류 모델링할 때 보통 tensorflow나 keras 라이브러리에 이미 포함되어 있는 MNIST, CIFAR-10 같은 이미지를 간단하게 load 하는 함수를 이용해서 toy project로 연습을 해보셨을 겁니다. 

그런데, 실제 이미지, 그림 파일을 분석해야 될 경우 '어? 이미지를 어떻게 업로드 하고, 어떻게 전처리하며, 어떻게 시각화해야 하는거지?'라는 의문을 한번쯤은 가져보셨을 듯 합니다. 

이번 포스팅에서는 바로 이 의문에 대한 답변 소개입니다. 


필요한 Python 라이브러리를 불러오겠습니다. 

 import numpy as np

 import pandas as pd

 import matplotlib.pyplot as plt

 import keras 



 1. 개와 고양이 사진 다운로드 (download dogs and cats images from Kaggle)

개와 고양이 사진을 아래의 Kaggle 사이트에서 다운로드 해주세요. Kaggle 회원가입을 먼저 해야지 다운로드 할 수 있습니다. 개는 1, 고양이는 0으로 라벨링이 되어 있는 25,000 개의 이미지를 다운받을 수 있습니다. 

https://www.kaggle.com/c/dogs-vs-cats/data



2. 개와 고양이 이미지 30개만 선택해서 별도 경로(폴더)에 복사하기


downloads 폴더에 들어있는 압축된 다운로드 파일을 압축 해제(unzip)해 주세요. 


윈도우 탐색기로 미리보기를 해보면 고양이 반, 개 반 입니다. 


directory, path 관리하는데 필요한 os 라이브러리, 파일을 source에서 destination 경로로 복사하는데 필요한 shutil 라이브러리를 불러오겠습니다. 

 import os # miscellaneous operating system interfaces

 import shutil # high-level file operations


이미지를 가져올 경로를 설정해보겠습니다. ('Downdoads/dogs-vs-cats/train' 경로에 train 폴더를 압축해제해 놓았습니다. 폴더 경로 확인 요함.)

# The path to the directory where the original dataset was uncompressed

 base_dir = '/Users/admin/Downloads'

 img_dir = '/Users/admin/Downloads/dogs-vs-cats/train'


train 폴더에 들어있는 개와 고양이 이미지가 총 25,000개 임을 확인했으며,  img_dir 경로에 포함되어 있는 이미지 중에서 10개만 indexing 해서 파일 제목을 확인해보았습니다. 

 len(os.listdir(img_dir))

 25000

os.listdir(img_dir)[:10]

['dog.8011.jpg',
 'cat.5077.jpg',
 'dog.7322.jpg',
 'cat.2718.jpg',
 'cat.10151.jpg',
 'cat.3406.jpg',
 'dog.1753.jpg',
 'cat.4369.jpg',
 'cat.7660.jpg',
 'dog.5535.jpg']


30개의 이미지만 샘플로 선별해서 다른 폴더로 복사해보겠습니다. 먼저, 30개 고양이 이미지를 담아둘 경로/ 폴더(cats30_dir) 를 만들어보겠습니다. 

# Directory with 30 cat pictures

 cats30_dir = os.path.join(base_dir, 'cats30')


 # Make a path directory

 os.mkdir(cats30_dir)


이제 source 경로에서 destination 경로로 shutil.copyfile(src, dst) 함수를 사용하여 고양이 이미지 30개만 이미지를 복사하겠습니다.  

# Copy first 30 cat images to cats30_dir

 fnames = ['cat.{}.jpg'.format(i) for i in range(30)]

 

 for fname in fnames:

     src = os.path.join(img_dir, fname)

     dst = os.path.join(cats30_dir, fname)

     shutil.copyfile(src, dst)


cats30_dir 경로로 복사한 30개의 고양이 이미지 파일 목록을 확인해 보았습니다. 

# check if pictures were copied well in cats30 directory

 os.listdir(cats30_dir)

['cat.6.jpg',
 'cat.24.jpg',
 'cat.18.jpg',
 'cat.19.jpg',
 'cat.25.jpg',
 'cat.7.jpg',
 'cat.5.jpg',
 'cat.27.jpg',
 'cat.26.jpg',
 'cat.4.jpg',
 'cat.0.jpg',
 'cat.22.jpg',
 'cat.23.jpg',
 'cat.1.jpg',
 'cat.3.jpg',
 'cat.21.jpg',
 'cat.20.jpg',
 'cat.2.jpg',
 'cat.11.jpg',
 'cat.10.jpg',
 'cat.12.jpg',
 'cat.13.jpg',
 'cat.9.jpg',
 'cat.17.jpg',
 'cat.16.jpg',
 'cat.8.jpg',
 'cat.28.jpg',
 'cat.14.jpg',
 'cat.15.jpg',
 'cat.29.jpg']



 3. 이미지 파일을 로딩, float array 로 변환 후 전처리하기
    (load image file and convert image data to float array format) 

Keras preprocessing 에 있는 image 클래스를 불러온 후, load_img() 함수를 사용해서 이미지 파일을 로딩하고, img_to_array() 함수를 사용해서 array 로 변환해보겠습니다. (Python OpenCV 라이브러리로도 가능함)

# a picture of one cat as an example

 img_name = 'cat.10.jpg'

 img_path = os.path.join(cats30_dir, img_name)


 # Preprocess the image into a 4D tensor using keras.preprocessing

 from keras.preprocessing import image


 img = image.load_img(img_path, target_size=(250, 250))

 img_tensor = image.img_to_array(img)


3차원 array에 이미지 샘플을 구분할 수 있도록 np.expand_dims() 함수를 사용하여 1개 차원을 추가하겠습니다. 그리고 [0, 1] 값 범위 내에 값이 존재하도록 array 값을 255.로 나누어서 표준화해주었습니다. 

  # expand a dimension (3D -> 4D)

 img_tensor = np.expand_dims(img_tensor, axis=0)

 img_tensor.shape

 (1, 250, 250, 3)

 

 # scaling into [0, 1]

 img_tensor /= 255.


첫번째 고양이 이미지의 array 데이터를 출력해보면 아래처럼 생겼습니다. 꼭 영화 메트릭스의 숫자들이 주루룩 내려오는 장면 같이 생겼습니다. 

img_tensor[0]

array([[[0.10196079, 0.11764706, 0.15294118],
        [0.07450981, 0.09019608, 0.1254902 ],
        [0.03137255, 0.04705882, 0.09019608],
        ...,
        [0.5058824 , 0.6313726 , 0.61960787],
        [0.49411765, 0.61960787, 0.60784316],
        [0.49019608, 0.6156863 , 0.6039216 ]],

       [[0.11764706, 0.13333334, 0.16862746],
        [0.13725491, 0.15294118, 0.1882353 ],
        [0.08627451, 0.10196079, 0.13725491],
        ...,
        [0.50980395, 0.63529414, 0.62352943],
        [0.49803922, 0.62352943, 0.6117647 ],
        [0.4862745 , 0.6117647 , 0.6       ]],

       [[0.11372549, 0.14117648, 0.16470589],
        [0.16470589, 0.19215687, 0.22352941],
        [0.15294118, 0.18039216, 0.21176471],
        ...,
        [0.50980395, 0.63529414, 0.62352943],
        [0.5019608 , 0.627451  , 0.6156863 ],
        [0.49019608, 0.6156863 , 0.6039216 ]],

       ...,

       [[0.69411767, 0.6431373 , 0.46666667],
        [0.6862745 , 0.63529414, 0.45882353],
        [0.6627451 , 0.6117647 , 0.4392157 ],
        ...,
        [0.7254902 , 0.70980394, 0.04313726],
        [0.6745098 , 0.6509804 , 0.03921569],
        [0.64705884, 0.6156863 , 0.05490196]],

       [[0.64705884, 0.5921569 , 0.45490196],
        [0.6117647 , 0.5568628 , 0.4117647 ],
        [0.5686275 , 0.5176471 , 0.3529412 ],
        ...,
        [0.7254902 , 0.7137255 , 0.01960784],
        [0.6862745 , 0.67058825, 0.00784314],
        [0.6509804 , 0.6313726 , 0.        ]],

       [[0.6039216 , 0.54901963, 0.4117647 ],
        [0.5882353 , 0.53333336, 0.3882353 ],
        [0.5803922 , 0.5294118 , 0.3647059 ],
        ...,
        [0.7254902 , 0.7137255 , 0.01960784],
        [0.6862745 , 0.67058825, 0.00784314],
        [0.6509804 , 0.6313726 , 0.        ]]], dtype=float32)



  4. 한개의 이미지 파일의 array 를 시각화하기 (visualizing an image array data)

matplotlib 라이브러리를 이용하여 위의 3번에서 이미지의 array 변환/ 전처리한 데이터를 시각화해보겠습니다. 예제로서 img_tensor[0] 으로 첫번째 고양이 이미지의 데이터를 시각화했습니다. 

# Image show

 import matplotlib.pyplot as plt

 plt.rcParams['figure.figsize'] = (10, 10) # set figure size

 

 plt.imshow(img_tensor[0])

 plt.show()




  5. 30개의 이미지 데이터를 6*5 격자에 나누어서 시각화하기 
    (visualizing 30 image data at 6*5 grid layout)

위의 3번에서 했던 이미지 파일 로딩, array로 변환, 1개 차원 추가, [0, 1] 범위로 표준화하는 전처리를 preprocess_img() 라는 이름의 사용자정의함수(UDF)로 만들었습니다. 

# UDF of pre-processing image into a 4D tensor

 def preprocess_img(img_path, target_size=100):

     from keras.preprocessing import image

     

     img = image.load_img(img_path, target_size=(target_size, target_size))

     img_tensor = image.img_to_array(img)

    

     # expand a dimension

     img_tensor = np.expand_dims(img_tensor, axis=0)

     

     # scaling into [0, 1]

     img_tensor /= 255.

     

     return img_tensor


이제 30개의 고양이 이미지 array 데이터를 사용해서 행(row) 6개 * 열(column) 5개의 격자 배열(grid layout) 에 시각화를 해보겠습니다. 이때 가독성을 높이기 위해서 고양이 사진 간에 검정색 구분선을 넣어서 시각화를 해보겠습니다. 

참고로, 아래 코드의 for loop 중간에 방금 전에 위에서 정의한 preprocess_img() 사용자정의함수 (빨간색으로 표기) 가 사용되었습니다. 

# layout

n_pic = 30

n_col = 5

n_row = int(np.ceil(n_pic / n_col))


# plot & margin size

target_size = 100

margin = 3


# blank matrix to store results

total = np.zeros((n_row * target_size + (n_row - 1) * margin, n_col * target_size + (n_col - 1) * margin, 3))


# append the image tensors to the 'total matrix'

img_seq = 0


for i in range(n_row):

    for j in range(n_col):


        fname = 'cat.{}.jpg'.format(img_seq)

        img_path = os.path.join(cats30_dir, fname)


        img_tensor = preprocess_img(img_path, target_size)


        horizontal_start = i * target_size + i * margin

        horizontal_end = horizontal_start + target_size

        vertical_start = j * target_size + j * margin

        vertical_end = vertical_start + target_size


        total[horizontal_start : horizontal_end, vertical_start : vertical_end, :] = img_tensor[0]

        

        img_seq += 1


# display the pictures in grid

plt.figure(figsize=(200, 200))

plt.imshow(total)

plt.show()


많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. 


728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 Greenplum Database, Postgresql Database에 사용할 수 있는 오픈소스 Database Tool인 DBeaver 설치, 사용법을 소개하겠습니다. 

그동안 PostgreSQL tool인 pgAdmin4 를 썼는데요, DBeaver가 더 나은 것 같아서 갈아 탔습니다. 

DBeaver는 PostgreSQL, Greenplum DB 외에도 MySQL, MariaDB, SQLite, Oracle, DB2, SQL Server, Sybase, MS Access, Teradata, Firebird, Derby 등의 Database에도 사용할 수 있으므로 활용도가 매우 높습니다. 물론 오픈소스니깐 공짜로 그냥 설치해서 사용하면 됩니다. 

* 출처: https://dbeaver.io/


  1, Mac OSX 에 DBeaver Community Edition (ver 5.3.5) 설치하기

저는 Brew 를 이용해서 설치했습니다. 

1. 터미널을 엽니다. 

2. Brew 가 설치되어 있지 않으면 아래의 스크립트를 그대로 실행시키고, 맥북의 비밀번호를 입력해주세요. 만약 Brew 를 이미 설치하셨다면 2번은 건너뛰고 3번만 실행시키면 됩니다.

ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" < /dev/null 2> /dev/null ; brew install caskroom/cask/brew-cask 2> /dev/null 

3. 터미널 창에 brew cask install dbeaver-community  를 실행합니다. 

MacBook-Pro:~ user$ brew cask install dbeaver-community

Updating Homebrew...

==> Auto-updated Homebrew!

Updated 1 tap (homebrew/core).

==> New Formulae

cafeobj                 gnunet                  homeassistant-cli       re-flex                 sd                      v2ray-plugin

gloo-ctl                h3                      i386-elf-grub           riff                    serve

==> Updated Formulae

git                               cdogs-sdl                           gcc                                 nwchem

kubernetes-helm                   cfengine                            gdk-pixbuf                          odpi

pcre                               cflow                               geckodriver                         offlineimap

abcde                               cfr-decompiler                      gecode                              ohcount

abcmidi                             cglm                                geocode-glib                        openssl@1.1

activemq-cpp                        chakra                              gerbil-scheme                       paket

aescrypt-packetizer                 check_postgres                      get_iplayer                         pandoc

afflib                              checkstyle                          git-lfs                             pandoc-citeproc

afio                                chkrootkit                          gitlab-runner                       parallel

agedu                               cli53                               glslang                             passenger

algernon                            click                               gnu-tar                             pdftoedn

amqp-cpp                            closure-compiler                    go                                  petsc

angular-cli                         cmark-gfm                           godep                               petsc-complex

annie                               cocoapods                           golang-migrate                      pgweb

ansible                             cointop                             gomplate                            phoronix-test-suite

apache-arrow                        collector-sidecar                   goreleaser                          php@7.1

apache-arrow-glib                   commandbox                          grafana                             picard-tools

apache-flink                        conan                               grpc                                planck

app-engine-java                     configen                            gwyddion                            plank

apt-dater                           confluent-oss                       gx                                  pmd

arangodb                            consul-template                     gx-go                               ponyc

aravis                              convox                              handbrake                           pre-commit

arm-linux-gnueabihf-binutils        coturn                              helmfile                            presto

armadillo                           couchdb                             hub                                 primesieve

arpack                              cpprestsdk                          i386-elf-binutils                   prometheus

artifactory                         cproto                              ibex                                protobuf

asciidoctorj                        crc32c                              imagemagick                         protobuf-c

asio                                cryptominisat                       ipfs                                protobuf-swift

ask-cli                             cryptopp                            jdupes                              protoc-gen-go

atkmm                               cscope                              jenkins                             pulumi

ats2-postiats                       csfml                               jhipster                            redis@4.0

auditbeat                           cython                              joplin                              rhash

aurora                              czmq                                kibana@5.6                          rust

autogen                             darcs                               kitchen-sync                        sbcl

avfs                                dartsim                             kompose                             sfml

aws-sdk-cpp                         davix                               kops                                shadowsocks-libev

awscli                              dcd                                 kube-ps1                            shellz

axel                                ddrescue                            kubeprod                            ship

azure-cli                           deark                               kubernetes-cli                      siege

azure-storage-cpp                   debianutils                         kustomize                           simutrans

babeld                              deja-gnu                            lcov                                singular

babl                                deployer                            ldc                                 skaffold

backupninja                         dhex                                lean-cli                            sn0int

bacula-fd                           dialog                              leiningen                           solr

balena-cli                          diffoscope                          libgweather                         spotbugs

batik                               diffstat                            libheif                             sqlmap

bazel                               digdag                              libphonenumber                      step

bee                                 dita-ot                             libpulsar                           supersonic

befunge93                           django-completion                   libqalculate                        svgo

bettercap                           docfx                               librealsense                        swagger-codegen

bgpstream                           docker                              libsecret                           swagger-codegen@2

bibtexconv                          docker-completion                   libtensorflow                       swiftformat

bigloo                              dovecot                             libxlsxwriter                       swiftlint

binaryen                            dpkg                                linkerd                             terragrunt

bind                                draco                               liquibase                           tgui

bindfs                              dscanner                            lmod                                thors-serializer

bit                                 dub                                 logtalk                             tippecanoe

blastem                             duck                                lzlib                               tmux-xpanes

bluetoothconnector                  dwdiff                              maxwell                             topgrade

bmake                               dwm                                 mesa                                typescript

boxes                               dyld-headers                        metricbeat                          unrar

brew-php-switcher                   dynamips                            minio-mc                            vagrant-completion

bro                                 eccodes                             mkl-dnn                             vault

buildifier                          elasticsearch                       mosh                                wabt

burp                                elasticsearch@5.6                   mosquitto                           wtf

bwm-ng                              elektra                             mysql@5.6                           xmrig

bzt                                 emscripten                          ncompress                           xtensor

c-blosc                             erlang@20                           nginx                               yara

caffe                               eslint                              nifi                                ydcv

calabash                            exploitdb                           node                                yle-dl

calcurse                            fabio                               node-build                          you-get

calicoctl                           flake8                              node@10                             youtube-dl

carrot2                             fn                                  node@6                              zbackup

cassandra@2.1                       frugal                              node@8

cassandra@2.2                       fx                                  ntopng

cdk                                 gambit-scheme                       numpy


==> Tapping homebrew/cask

Cloning into '/usr/local/Homebrew/Library/Taps/homebrew/homebrew-cask'...

remote: Enumerating objects: 4086, done.

remote: Counting objects: 100% (4086/4086), done.

remote: Compressing objects: 100% (4075/4075), done.

remote: Total 4086 (delta 24), reused 442 (delta 8), pack-reused 0

Receiving objects: 100% (4086/4086), 1.31 MiB | 593.00 KiB/s, done.

Resolving deltas: 100% (24/24), done.

Tapped 1 command and 3985 casks (4,093 files, 4.2MB).

==> Caveats

dbeaver-community requires Java 8+. You can install the latest version with


  brew cask install java


==> Satisfying dependencies

==> Downloading https://github.com/dbeaver/dbeaver/releases/download/5.3.5/dbeaver-ce-5.3.5-macos.dmg

==> Downloading from https://github-production-release-asset-2e65be.s3.amazonaws.com/44662669/a1006c00-3315-11e9-84bc-679ab5a9b0aa?X-Amz-Algor

######################################################################## 100.0%

==> Verifying SHA-256 checksum for Cask 'dbeaver-community'.

==> Installing Cask dbeaver-community

==> Creating Caskroom at /usr/local/Caskroom

==> We'll set permissions properly so we won't need sudo in the future.

Password:

==> Moving App 'DBeaver.app' to '/Applications/DBeaver.app'.

🍺  dbeaver-community was successfully installed!

MacBook-Pro:~ user$ 



  2. Java JDK 설치 하기

Java JDK 가 설치되어 있지 않으면 'Java JDK를 설치하세요'라는 메시지가 뜹니다. (JDK가 설치되어 있다면 2번은 건너뛰면 됩니다)

java 설치 여부 및 버전은 아래처럼 java -version 으로 터미널에서 확인해볼 수 있습니다. 저는 Java 가 없으니 설치가 필요(requesting install)하다고 메시지가 나오네요. 

MacBook-Pro:~ user$ java -version

No Java runtime present, requesting install.


Oracle 의 아래 주소에서 macOS용 jdk-11.0.2_osx_x64_bin.dmg 파일을 다운로드 받았습니다. 

[다운로드 주소]

https://www.oracle.com/technetwork/java/javase/downloads/jdk11-downloads-5066655.html


Linux, macOS, Windows 중에서 자신의 OS에 맞는 것을 선택해서 다운로드 하면 됩니다. 이때 Oracle License Agreement 를 accept 한다고 체크를 해주어야 합니다. 


jdk-11.0.2_osx-x64.dmg 파일이 다운로드 완료되면 아이콘을 더블 클릭해서 설치 애플리케이션을 시작합니다. 가운데 아이콘을 클릭한 다음에 '계속' 단추를 누르면서 설치를 합니다. 맥북 비밀번호 입력하라는 창이 뜨면 비밀번호를 입력해주면 설치가 완료됩니다. 



JDK가 잘 설치되었는지 java -version으로 확인해보겠습니다.

MacBook-Pro:~ user$ java -version

java version "11.0.2" 2019-01-15 LTS

Java(TM) SE Runtime Environment 18.9 (build 11.0.2+9-LTS)

Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.2+9-LTS, mixed mode) 



  3. Docker로 Greenplum DB 설치하고 실행하기

자세한 내용은 아래의 블로그 포스팅과 Docker Hub를 참고하시기 바랍니다. 

==>  https://rfriend.tistory.com/379

==> https://hub.docker.com/r/hdlee2u/gpdb-analytics

(터미널 사용)

## Docker 이미지 내려 받기

$ docker pull hdlee2u/gpdb-analytics

## Docker 이미지 확인 하기

$ docker images

REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE

hdlee2u/gpdb-analytics  latest           3be773a1a7e1        About a minute ago   4.93GB

## Docker 이미지를 실행/ 5432를 기본 포트로, ssh를 2022포트를 사용하여 접근 가능하도록 Docker 컨테이너 생성

$ docker run -i -d -p 5432:5432 -p 28080:28080 --name gpdb-ds --hostname mdw hdlee2u/gpdb-analytics /usr/sbin/sshd -D


## Docker 컨테이너 목록 확인

$ docker ps

CONTAINER ID    IMAGE                   COMMAND                   CREATED             STATUS              PORTS                   NAMES

7518fd48450a        575a7d45999d        "/bin/bash"              1 minute ago         Up 6 hours                  0.0.0.0:5432->5432/tcp, 0.0.0.0:28080->28080/tcp   gpdb-ds


## Start GPDB and Use psql

$ docker exec -it gpdb-ds /bin/bash

[root@mdw /]# su - gpadmin

[gpadmin@mdw ~]$ gpstart -a



  4. DBeaver 실행하고, Greenplum DB 연결 설정하기 (GPDB connect)

맥북의 Launchpad에서 DBeaver 아이콘을 클릭하면 아래와 같은 DBeaver가 실행됩니다. 'Select your database' 화면창에서 'PostgreSQL'을 선택하고 '다음(Next)'을 선택합니다. 


Connection Settings 화면이 나오면 (3번에서 소개한 docker image 로 Greenplum DB를 론칭한 경우) 

 - Host: localhost

 - Database: gpadmin

 - User: gpadmin

 - Password: pivotal

 - Port: 5432

로 입력해주세요. 만약 다른 환경의 Greenplum DB를 사용하고 있다면 그에 맞게 Host, Database, User, Password를 설정해주면 됩니다. 


Greenplum Database에 DBeaver tool이 제대로 연결이 되면 아래 화면처럼 왼쪽 분할면에 Database, Schema, Tables 네비게이터가 나타나고, 테이블을 하나 선택하면 오른쪽는 Data 셋을 Grid나 Text 형태로 볼 수 있습니다. 

(테이블의 데이터 사이즈가 엄청 큰 경우에는 테이블을 클릭해서 Data 보기를 하지 마시기 바랍니다. DB가 다운되어서 DB관리자에게 요주의 인물로 찍히는 수가 있습니다. SQL Editor 창에서 select 문으로 limit  걸어서 조회하시기 바랍니다.)


SQL Editor 는 상단 메뉴에서 'SQL Editor'를 선택하거나, 또는 상단 메뉴바에서 '말아놓은 종이모양 아이콘'을 클릭하면 됩니다. 


SQL select 문을 쓸 때 from 절의 테이블 이름은 좌측 분할면의 Navigator 창에서 해당 테이블을 마우스로 드래그 & 드랍해서 SQL Editor의 from 절 다음에 가져다 놓으면 schmema_name.table_name 이 자동으로 써지므로 편리하게 이용할 수 있습니다. 

SQL Editor에 쓴 SQL query를 실행할 때는 'control(^) + enter' 를 누르거나, SQL Editor 창의 세모 (아래 화면 캡쳐의 빨간색 부분) 아이콘을 누르면 됩니다. 


이상으로 DBeaver 설치 및 DBeaver를 Greenplum Database에 연결하고 DB, Schema, Table 보기 및 Query 실행하는 방법에 대해서 알아보았습니다. 


많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. 


728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 os 라이브러리를 이용한 경로 및 폴더 관리, shutil 라이브러리를 이용한 파일 복사 방법에 대한 소소한 팁들을 소개하겠습니다. 

os 라이브러리에 대해서 소개해 놓은 페이지 ( https://docs.python.org/3/library/os.html )에 가보면 '기타 운영 체계에 대한 인터페이스 (Miscellaneous operating system interfaces)' 라고 소개를 하면서 스크롤 압박에 굉장히 심할 정도로 여러개의 함수들을 소개해 놓았습니다. 

그 많은 것을 모두 소개하기는 힘들구요, 그중에서도 이번 포스팅에서는 제가 자주 쓰는 함수들만 몇 개 선별해서 소개하도록 하겠습니다. 


  1. os 라이브러리를 이용한 경로 및 폴더 생성, 조회, 변경


먼저 os 라이브러리를 불러오겠습니다. 


import os # Miscellaneous operating system interfaces



1-1. 현재 작업경로 확인하기: os.getcwd()


# os.getcwd(): returns the current working directory

os.getcwd()

'C:\\Users\\admin\\python'

 



1-2. 작업경로 안에 들어있는 파일 리스트 확인하기: os.listdir(path)


# os.listdir(path): return a list of then entries in the directory given by path

os.listdir(os.getcwd()) # a list of files at current directory

['.ipynb_checkpoints', 'numpy_adding_new_axis.ipynb', 'Numpy_clip.ipynb', 'python_os.ipynb'] 




1-3. 작업경로 바꾸기: os.chdir(path)


# os.chdir(path): change the current working directory to path

base_dir = 'C:/Users/admin'

os.chdir(base_dir)

os.getcwd()

 'C:\\Users\\admin'




1-4. 기존 경로와 새로운 폴더 이름을 합쳐서 하위 경로 만들기: os.path.join()


# join one or more path components

path = os.path.join(base_dir, 'os')

path

'C:/Users/admin\\os'




1-5. 새로운 폴더를 만들기: os.mkdir(path)

 

# create a directory named path with numeric mode

os.mkdir(path)




1-6. 경로가 존재하는지 확인하기: os.path.isdir(path)


# return True if path is an existing directory

os.path.isdir(path)

True

 



1-7. 파일이나 경로 이름 바꾸기: os.rename(old_path_name, new_path_name)


# rename the file or directory src to dst

# os.rename(src, dst)

dst_path = os.path.join(base_dir, 'os_renamed')

os.rename(path, dst_path)

os.path.isdir(dst_path) # check whether dst_path is renamed or not

True

 



  2. shutil 라이브러리를 이용한 파일 복사: shutil.copyfile(src, dst)


먼저, 파일을 복사해올 소스 경로(source directory, from)와 파일을 복사해놓은 종착지 경로(destination directory, to)를 만들어보겠습니다. 


# creating src_dir, dst_dir

base_dir = 'C:/Users/admin'

src_dir = os.path.join(base_dir, 'src_dir')

dst_dir = os.path.join(base_dir, 'dst_dir')


os.mkdir(src_dir)

os.mkdir(dst_dir)

 


다음으로, 소스 경로(src_dir)에 'file_1.txt', 'file_2.txt', 'file_3.txt' 라는 이름으로 메모장으로 작성한 간단한 텍스트 파일 3개를 저장해두었습니다. (직접 수작업으로 메모장 열고 문자 몇개 입력하고 저장함)

os.listdir() 를 사용하여 소스 경로(src_dir)에 들어있는 3개의 텍스트파일 이름을 fnames 라는 이름의 리스트로 만들어두었습니다. 


# put file_1, file_2, file_3 into src_dir

fnames = os.listdir(src_dir)

fnames

['file_1.txt', 'file_2.txt', 'file_3.txt'] 



마지막으로, shutil 라이브러리를 불러오고, shutil.copyfile(src, dst) 함수를 사용하여 소스 경로(source directory)에 들어있는 3개의 텍스트 파일을 종착지 경로(destination directory)로 복사해보겠습니다. 

이때 for loop 문을 사용하여 텍스트 파일 별로 shutil.copyfile(src, dst)를 적용해주면 됩니다. 


# copy files from src to dst directory

import shutil


for fname in fnames:

    src = os.path.join(src_dir, fname)

    dst = os.path.join(dst_dir, fname)

    shutil.copyfile(src, dst)


os.listdir(dst_dir)

['file_1.txt', 'file_2.txt', 'file_3.txt'] 




  3. os와 shutil 라이브러리를 이용한 폴더 삭제, 파일 삭제하기


아래와 같이 3개의 텍스트 파일이 들어있는 'C:/Users/admin/os' 라는 경로의 폴더를 예로 들어보겠습니다. 


os.listdir('C:/Users/admin/os')

['big_data.txt', 'my_data.txt', 'sample_data.txt']



3-1. 경로(폴더) 제거하기: os.rmdir(path)

경로(폴더) 안에 파일이 없어야지 os.rmdir()을 사용할 수 있습니다. 경로(폴더) 안에 파일이 있으면 아래처럼 "OSError: [WinError 145] 디렉토리가 비어 있지 않습니다"라는 에러가 발생합니다. 


# OSError: directory is not empty 

os.rmdir('C:/Users/admin/os')

---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
<ipython-input-11-4b25f55d427c> in <module>()
----> 1 os.rmdir('C:/Users/admin/os')

OSError: [WinError 145] 디렉터리가 비어 있지 않습니다: 'C:/Users/admin/os'


os.path.isdir(dst_path) # check whether dst_path is removed or not

False

 


3-2. 파일 삭제하기 : os.remove(path)

os.remove() 는 인자로 1개의 파일 경로를 받습니다. 한번에 한개씩 지워야 하므로 불편한점이 있습니다. 


 # delete file

os.remove('C:/Users/admin/os/my_data.txt')

os.remove('C:/Users/admin/os/big_data.txt')

os.remove('C:/Users/admin/os/sample_data.txt')



위에서 'C:/Users/admin/os' 경로 안의 파일 3개를 모두 삭제했으므로 이제 os.rmdir() 을 사용해서 폴더를 삭제할 수 있습니다. 

# delete directory only when it is empty

os.rmdir('C:/Users/admin/os') 


경로(폴더)가 존재하는지 os.path.isdir(path)로 확인해보겠습니다. 방금전에 경로를 os.rmdir()로 삭제를 했기 때문에 False 를 반환하였습니다. 

# check whether the directory is present or not

os.path.isdir('C:/Users/admin/os') 

False


3-3. 경로(폴더)와 파일을 한꺼번에 모두 삭제하기 : shutil.rmtree(path)


os.mkdir('C:/Users/admin/os')


# delete directory and files at once

import shutil

shutil.rmtree('C:/Users/admin/os')

 


많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. :-)

728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 Python Numpy 배열 (array)에 차원을 추가하는 3가지 방법을 소개하겠습니다. 딥러닝 공부하다 보면 computer vision의 CNN에서 이미지 파일을 불러와서 다차원 배열로 변환할 때 사용하곤 합니다. 

1. numpy.reshape() 을 이용한 차원 추가

2. numpy.expand_dims() 을 이용한 차원 추가

3. numpy.newaxis 을 이용한 차원 추가


예제로 사용할 간단한 (4, 3, 2) 3차원의 다차원 배열을 만들어보겠습니다. 


import numpy as np

a = np.arange(24).reshape(4, 3, 2)

a

array([[[ 0,  1],
        [ 2,  3],
        [ 4,  5]],

       [[ 6,  7],
        [ 8,  9],
        [10, 11]],

       [[12, 13],
        [14, 15],
        [16, 17]],

       [[18, 19],
        [20, 21],
        [22, 23]]])

a.shape

(4, 3, 2)




(4, 3, 2) 차원의 배열 a에 차원을 추가하여 (1, 4, 3, 2)의 4차원 배열로 만들어보겠습니다. 


  1. numpy.reshape() 를 이용한 차원 추가


 

np.reshape(a, (1, 4, 3, 2))

array([[[[ 0,  1],
         [ 2,  3],
         [ 4,  5]],

        [[ 6,  7],
         [ 8,  9],
         [10, 11]],

        [[12, 13],
         [14, 15],
         [16, 17]],

        [[18, 19],
         [20, 21],
         [22, 23]]]])


 np.reshape(a, ((1,) + a.shape))

array([[[[ 0,  1],
         [ 2,  3],
         [ 4,  5]],

        [[ 6,  7],
         [ 8,  9],
         [10, 11]],

        [[12, 13],
         [14, 15],
         [16, 17]],

        [[18, 19],
         [20, 21],
         [22, 23]]]])

 a.reshape((1,) + a.shape)

array([[[[ 0,  1],
         [ 2,  3],
         [ 4,  5]],

        [[ 6,  7],
         [ 8,  9],
         [10, 11]],

        [[12, 13],
         [14, 15],
         [16, 17]],

        [[18, 19],
         [20, 21],
         [22, 23]]]])



  2. numpy.expand_dims() 를 이용한 차원 추가



np.expand_dims(a, axis=0)

array([[[[ 0,  1],
         [ 2,  3],
         [ 4,  5]],

        [[ 6,  7],
         [ 8,  9],
         [10, 11]],

        [[12, 13],
         [14, 15],
         [16, 17]],

        [[18, 19],
         [20, 21],
         [22, 23]]]])

 



  3. numpy.newaxis 를 이용한 차원 추가



a[:, np.newaxis]

array([[[[ 0,  1],
         [ 2,  3],
         [ 4,  5]]],


       [[[ 6,  7],
         [ 8,  9],
         [10, 11]]],


       [[[12, 13],
         [14, 15],
         [16, 17]]],


       [[[18, 19],
         [20, 21],
         [22, 23]]]])

 


많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. :-)

728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 행 기준으로 숫자형 변수들의 합을 구한 다음에, 그룹별로 행 기준 합이 최대인 전체 행을 선별하는 방법을 소개하겠습니다. 


말로 설명한 내용만으로는 얼른 이해가 안 올 수도 있겠는데요, 이번에 해볼 내용은 아래의 이미지를 참고하시면 이해가 쉬울 듯 합니다. 




예제로 사용할 하나의 그룹 변수(V1)와 나머지 9개의 숫자형 변수(V2~V10)로 구성된 간단한 DataFrame을 만들어보겠습니다. 



> ##------------------------------------------------------

> ## selecting distinct object using dplyr chain operator

> ##------------------------------------------------------

> rm(list=ls())

> set.seed(123) # for reproducibility

> V1 <- c(rep("apple", 5), rep("banana", 5), rep("tomato", 5)) # group

> V2 <- sample(x=1:10, size=15, replace=T)

> V3 <- sample(x=1:10, size=15, replace=T)

> V4 <- sample(x=1:10, size=15, replace=T)

> V5 <- sample(x=1:10, size=15, replace=T)

> V6 <- sample(x=1:10, size=15, replace=T)

> V7 <- sample(x=1:10, size=15, replace=T)

> V8 <- sample(x=1:10, size=15, replace=T)

> V9 <- sample(x=1:10, size=15, replace=T)

> V10 <- sample(x=1:10, size=15, replace=T)

> df <- data.frame(V1, V2, V3, V4, V5, V6, V7, V8, V9, V10)

> df

       V1 V2 V3 V4 V5 V6 V7 V8 V9 V10

1   apple  3  9 10  2  7  3  2  9   7

2   apple  8  3 10  3  1  4  7 10   4

3   apple  5  1  7  5  4  7  4  7   4

4   apple  9  4  8  3  3  4  7  5   3

5   apple 10 10  1  9  9  2  4  2   4

6  banana  1  9  5  1  5  3  2 10  10

7  banana  6  7  8  5  9  7  8  4   2

8  banana  9  7  3  8  9  5  1  1   1

9  banana  6 10  4  2  8  8  5 10   2

10 banana  5  7  3  6  5  2  6  8   7

11 tomato 10  8  2  3  8  5  6  2   7

12 tomato  5  6  5  2  7 10  4  6   9

13 tomato  7  6  5  8  8  9  5 10   7

14 tomato  6  3  4  9  1  9 10  6   8

15 tomato  2  2  2  4  5  2  5  5   6

 

> rm(V1, V2, V3, V4, V5, V6, V7, V8, V9, V10)





rowSums() 함수를 사용하여서 행(row) 기준의 숫자형 변수들 모두에 대해 합계를 구하여 'V_sum' 이라는 새로운 변수를 추가해보겠습니다. 



> # summation in a row direction

> df$V_sum <- rowSums(df[,2:10])

> df

       V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V_sum


1   apple  3  9 10  2  7  3  2  9   7    52

2   apple  8  3 10  3  1  4  7 10   4    50

3   apple  5  1  7  5  4  7  4  7   4    44

4   apple  9  4  8  3  3  4  7  5   3    46

5   apple 10 10  1  9  9  2  4  2   4    51


6  banana  1  9  5  1  5  3  2 10  10    46

7  banana  6  7  8  5  9  7  8  4   2    56

8  banana  9  7  3  8  9  5  1  1   1    44

9  banana  6 10  4  2  8  8  5 10   2    55

10 banana  5  7  3  6  5  2  6  8   7    49


11 tomato 10  8  2  3  8  5  6  2   7    51

12 tomato  5  6  5  2  7 10  4  6   9    54

13 tomato  7  6  5  8  8  9  5 10   7    65

14 tomato  6  3  4  9  1  9 10  6   8    56

15 tomato  2  2  2  4  5  2  5  5   6    33

 




위의 행 기준 합계로 보면 'apple' 그룹에서는 1번째 행의 합이 52로 가장 크며, 'banana' 그룹에서는 7번째 행의 합이 56으로서 가장 크고, 'tomato' 그룹에서는 13번째 행의 합이 65로서 가장 큽니다. 이를 1번째, 7번째, 13번째 전체 행을 선별해보겠습니다. (빨간색으로 표시한 부분)



> library(dplyr)

> df_group_distinct_max <- df %>% 

+   arrange(V1, desc(V_sum)) %>% 

+   group_by(V1) %>% slice(1:1)

> df_group_distinct_max <- data.frame(df_group_distinct_max[1:10])

> df_group_distinct_max

      V1 V2 V3 V4 V5 V6 V7 V8 V9 V10

1  apple  3  9 10  2  7  3  2  9   7

2 banana  6  7  8  5  9  7  8  4   2

3 tomato  7  6  5  8  8  9  5 10   7

 


* dplyr 패키지 사용법은 

https://rfriend.tistory.com/234 , 

https://rfriend.tistory.com/236

참고하시기 바랍니다


많은 도움이 되었기를 바랍니다. 


이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. ^^



728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 배열(array)에서 0보다 작은 수는 0으로 변환하고 나머지는 그대로 두는 여러가지 방법을 소개하겠습니다. 


1. List Comprehension with for loop

2. Indexing

3. np.where(condition[, x, y])

4. np.clip(a, a_min, a_max, out=None)





  1. List Comprehension: [0 if i < 0 else i for i in a]


아래처럼 for loop 을 써서 list comprehension 방법을 사용하면 특정 라이브러리의 함수를 사용하지 않아도 0보다 작은 수는 0으로 변환할 수 있습니다. 하지만, for loop 을 돌기 때문에 배열(array)가 커지면 성능이 문제될 수 있습니다.  원래의 배열 a는 그대로 있습니다. 



>>> import numpy as np

>>> a = np.arange(-5, 5)

>>> a

array([-5, -4, -3, -2, -1,  0,  1,  2,  3,  4])

>>> [0 if i < 0 else i for i in a]

[0, 0, 0, 0, 0, 0, 1, 2, 3, 4]

>>> a

array([-5, -4, -3, -2, -1,  0,  1,  2,  3,  4])





  2. Indexing: a[a < 0] = 0


아래처럼 indexing을 사용해서 a[a < 0] = 0 처럼 0보다 작은 값이 위치한 곳에 0을 직접 할당할 수 있습니다. 이렇게 하면 원래의 배열 a가 변경됩니다. 



>>> a = np.arange(-5, 5)

>>> a

array([-5, -4, -3, -2, -1,  0,  1,  2,  3,  4])

>>> a[a < 0] = 0

>>> a

array([0, 0, 0, 0, 0, 0, 1, 2, 3, 4])

 




  3. np.where() : np.where(a < 0, 0, a)


np.where(조건, True일 때 값, False일 때 값) 를 사용하면 편리하게 0보다 작은 조건의 위치에 0을 할당할 수 있습니다. 벡터 연산을 하므로 for loop이 돌지 않아서 속도가 매우 빠릅니다. 원래의 배열 a는 변경되지 않고 그대로 있습니다. 



>>> a = np.arange(-5, 5)

>>> a

array([-5, -4, -3, -2, -1,  0,  1,  2,  3,  4])

>>> np.where(a < 0, 0, a)

array([0, 0, 0, 0, 0, 0, 1, 2, 3, 4])

>>> a

array([-5, -4, -3, -2, -1,  0,  1,  2,  3,  4])

 



만약 0보다 작은 수는 0으로 변환, 2보다 큰 수는 2로 변환하고 싶다면 아래처럼 np.where() 안에 np.where()를 한번 더 넣어서 써주면 되는데요, 코드가 좀 복잡해보입니다. 



>>> a = np.arange(-5, 5)

>>> a

array([-5, -4, -3, -2, -1,  0,  1,  2,  3,  4])

>>>

>>> np.where(a < 0, 0, np.where(a > 2, 2, a))

array([0, 0, 0, 0, 0, 0, 1, 2, 2, 2])

 




  4. np.clip() : np.clip(a, 0, 4, out=a)


np.clip(배열, 최소값 기준, 최대값 기준) 을 사용하면 최소값과 최대값 조건으로 값을 기준으로 해서, 이 범위 기준을 벗어나는 값에 대해서는 일괄적으로 최소값, 최대값으로 대치해줄 때 매우 편리합니다. 최소값 부분을 0으로 해주었으므로 0보다 작은 값은 모두 0으로 대치되었습니다. 이때 원래의 배열 a는 그대로 있습니다. 



>>> a = np.arange(-5, 5)

>>> a

array([-5, -4, -3, -2, -1,  0,  1,  2,  3,  4])

>>> np.clip(a, 0, 4)

array([0, 0, 0, 0, 0, 0, 1, 2, 3, 4])

>>> a

array([-5, -4, -3, -2, -1,  0,  1,  2,  3,  4])

 



np.clip(배열, 최소값 기준, 최대값 기준, out 배열)을 사용해서 out = a 를 추가로 설정해주면 반환되는 값을 배열 a에 저장할 수 있습니다. 배열 a의 0보다 작았던 부분이 모두 0으로 대치되어 a가 변경되었음을 확인할 수 있습니다. 



>>> np.clip(a, 0, 4, out=a)

array([0, 0, 0, 0, 0, 0, 1, 2, 3, 4])

>>> a

array([0, 0, 0, 0, 0, 0, 1, 2, 3, 4])

 



최소값 기준만 적용해서 간단하게 '0'보다 작은 수는 모두 0으로 바꾸는 것은 a.clip(0) 처럼 메소드를 사용해도 됩니다. 



>>> a = np.arange(-5, 5)

>>> a

array([-5, -4, -3, -2, -1,  0,  1,  2,  3,  4])

>>> a.clip(0)

array([0, 0, 0, 0, 0, 0, 1, 2, 3, 4])

 



많은 도움이 되었기를 바랍니다. 


이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. ^^



728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 그래픽카드 확인하는 방법, Tensorflow와 Keras가 GPU를 사용하고 있는지 확인하는 방법, GPU 사용율 모니터링하는 방법을 알아보겠습니다. 



아래는 Windows10 기준의 설명입니다. 



  1. 컴퓨터 그래픽 카드가 NVIDIA Graphics Card 인지 확인하는 방법


키보드에서 'Windows로고 + R'을 누르거나, 마우스 오른쪽으로 'Windows로고'를 선택한 후 '실행(R)'을 선택하면 아래처럼 '실행' 창이 나타납니다. 이 실행창의 열기(O) 칸에 'dxdiag'를 입력하고 '확인'을 누릅니다. 




그러면 아래처럼 'DirectX 진단 도구' 화면이 나타납니다. 여기서 '디스플레이1' 메뉴를 선택하면 그래픽카드를 볼 수 있습니다. 제조업체가 NVIDIA 인지 확인하고, CUDA, CUDNN 지원하는지 확인합니다. 





  2. Tensorflow, Keras코드가 GPU에서 돌아가고 있는지 확인하는 방법


Nvidia GPU 그래픽카드가 설치되어 있는 컴퓨터에 (0) Visual Studio 설치, (1) CUDA 설치, (2) CUDNN 설치, (3) Anaconda 설치, (4) 가상환경 생성 및 tensorflow-gpu 설치, (5) Jupyter notebook에 가상환경 커널 추가 등의 작업을 마쳤다면 GPU를 사용하여 딥러닝 모델을 훈련시킬 수 있습니다. 


* Windows10 환경에서 tensorflow gpu 설치 참고: https://smprlab.tistory.com/21


Tensorflow, Keras코드가 GPU에서 돌아가는지 아니면 CPU에서 돌아가고 있는지 확인하는 방법은 아래와 같습니니다. 



import numpy as np

import pandas as pd


import keras

import tensorflow as tf

from IPython.display import display

import PIL

 



# How to check if the code is running on GPU or CPU?

from tensorflow.python.client import device_lib

print(device_lib.list_local_devices())

[name: "/cpu:0"
device_type: "CPU"
memory_limit: 268435456
locality {
}
incarnation: 4800764240957379342
, name: "/gpu:0"
device_type: "GPU"
memory_limit: 6814913823
locality {
  bus_id: 1
}
incarnation: 14858485129082007400
physical_device_desc: "device: 0, name: GeForce GTX 1070, pci bus id: 0000:01:00.0"
]

 



# How to check if Keras is using GPU?

from keras import backend as K

K.tensorflow_backend._get_available_gpus()


['/gpu:0']

 




  3. 딥러닝 모델 훈련 시 GPU 사용율 확인하는 방법


'Windows로고'에 마우스 오른쪽 클릭을 한 후, 아래의 메뉴화면에서 '작업 관리자(T)'를 선택합니다. 




그러면, 아래처럼 '작업 관리자' 화면이 나타나는데요, 그 중에서 '성능' 탭 메뉴를 선택한 후, 상세 항목에서 'GPU'를 선택해주면 아래 화면처럼 GPU 메모리 사용량을 실시간으로 확인할 수 있습니다. 




많은 도움이 되었기를 바랍니다. 


이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. :-)



728x90
반응형
Posted by Rfriend
,