다양한 데이터 다루기 


0. 다양한 리스트 다루기 

# 첫번째 값 리턴
a = [1, 2, 3]
print a[0]

# 마지막값 리턴
print a[-1]

# 리스트안의 리스트에서 값 가져오기
b = [1, 2, 3, ['a', 'b', 'c']]
print b[3][0] # 'a' 리턴

# 리스트 슬라이싱 하기
print b[0:2] # [1,2] 리턴

#리스트 삭제
c = [1, 2, 3, 4, 5, 6, 7]
c.pop(0) # 첫번째 값 삭제
del c[1] # 두번째값 삭제
c.remove(4) # 리스트에서 첫번째로 나오는 4 삭제
c=[] #전체삭제

# 리스트 정렬
d = [1, 9, 3, 2, 5, 14, 7,4]
d.sort()

# 리스트 값 삽입
d.insert(0,4) # 0번째 위치에 4 삽입

# 리스트에서 특정 요소의 갯수 세기
d.count(4) # 리스트에 None 이 없다면 if None not in shaplet:


1. 리스트에서 같은 값의 카운트 세기 

import collection.Counter

c = Counter("문재인", "문재인", "안희정", "안희정", "안철수","이재명", "이재명")
c["문재인"] 2


2. 리스트에서 특정 값만 솎아내기 

 a = [1,2,3,4,5] 중에서 홀수만 골라내기  

람다식을 이용하면 아래와 같이 됩니다.

filter (lambda x : x % 2 , a)   

근데 이것을 List comprehension 으로 표현하면

 [x for x in a if x % 2] 


3. 두개 리스트의 요소를 곱하기 

일반

[a * b for a, b in zip(lista, listb)]

numpy 이용 

import numpy as np
a = np.array([1, 2, 3, 4])
b = np.array([2, 3, 4, 5])
a * b
array([2, 6, 12, 20])


4. 리스트에서 index 와 값을 뽑아내서 순회하기 (enumerate 이용) 

[i for i, x in enumerate(testlist) if x == 1]


5. 리스트에서 몇개씩 가져오기 ( 예를들어 48개의 데이터에서 24개씩 가져오기) 

def group(iterator, count):
itr = iter(iterator)
while True:
yield [itr.next() for i in range(count)]

for item in group(watts,24):

이렇게 사용하면 watts 라는 리스트에 있는 데이터에서 24개씩 가져온다. 


6. reduce 와  operator.add 를 이용해서 합구하기 


import operator

def sum(numbers):
return reduce(operator.add, numbers, 0)


7. min 함수의 강력함 ( 데이터를 비슷한 것 끼리 3등분하기) 

import random

k = 3
inputs = [1,5,6,50,55,60,100,111,132]
means = random.sample(inputs, k)

def classify_1dim(input):
return min(range(k), key=lambda i: abs(input - means[i]))

new_assignments = map(classify_1dim, inputs)

결과: [0,0,0,1,1,1,2,2,2] 

설명 :
map(classify_1dim, inputs) 는 inputs 리스트에서 하나씩 classify_1dim 에 적용시킨다.
min (range(k), key=lambda i : abs(input - means[i])) 은 들어온 input 를 means[0], means[1], means[2] 와 각각의 차를 구한 후에 가장 낮은 숫자에 대한 인덱스를 리턴해준다.

결국 new_assignments 에는 inputs 리스트값들이 가장 가까운  means[0], means[1], means[2]  중 하나로 매핑되어 진다.


시나리오가 있는 데이터 다루기

@ 아래와 같은 주식 데이터가 있다고 하자.  / 종가 / 날짜 / 심볼로 이루어져있다.

symbol date closing_price
AAPL 2015-01-23 112.98
AAPL 2015-01-22 112.4
AAPL 2015-01-21 109.55
AAPL 2015-01-20 108.72
AAPL 2015-01-16 105.99
AAPL 2015-01-15 106.82
AAPL 2015-01-14 109.8
..


 심볼이 'AAPL' 인 것들 중에서  가장 높은 가격 산출

max_aapl_price = max(row["closing_price"]
for row in data if row["symbol"] == "AAPL")

data 컬렉션에서 값(row) 을 하나 가져와서  심볼이 "AAPL" 인것들 중에서 값이 가장 높은것


심볼별로 데이터 그룹화

from collections import defaultdict
# group rows by symbol
by_symbol = defaultdict(list)

for row in data:
by_symbol[row["symbol"]].append(row)

심볼이 같은것 끼리 묶어 줍니다. 즉 { "AAPL" : [ ... , ... ]  , "BBPL" : [ ..., ... ]  .......} 이런식으로요~


그룹별 가장 높은 가격 

max_price_by_symbol = {symbol: max(row["closing_price"] for row in grouped_rows)
for symbol, grouped_rows in by_symbol.iteritems()}

위에서 심볼별 리스트들을 가져와서 각각에 대한 가장 높은 값을 구해줍니다.

결과는 {'AAPL': 119.0, 'FB': 38.23, 'MSFT': 22.78}


특정필드를 리스트로 추출  

def picker(field_name):
return lambda row: row[field_name]

def pluck(field_name, rows):
return map(picker(field_name), rows)

picker 는 특정 필드의 값을 리턴해주는 함수를 반환합니다.
pluck 는 rows 들 중 특정 필드의 값 만으로 리스트를 만들어 줍니다.  
즉 field_name 에 "closing_price" 를 입력해주면 , 그 값들로만 이루어진 리스트를 리턴함. 


데이터를 그룹화시켜서 모으고 , value_transform 공식에 의해서 변경시킨다. 

def group_by(grouper, rows, value_transform=None):
grouped = defaultdict(list)
for row in rows:
grouped[grouper(row)].append(row)
if value_transform is None:
return grouped
else:
return {key: value_transform(rows)
for key, rows in grouped.iteritems()}

심볼이라든지 어떤 특정 것을 구분하여 그룹화시키고 , 각 그룹을 value_transform 에 의해 계산합니다.
value_transform  가 그룹의 max 값을 찾는 것이라면 {"AAPL" : 1030 , "BBPL" : 2000 ..} 뭐 이런식으로 결과가 나오겠지요.




itertools 


소개

Python 에서 제공하는 자신만의 반복자를 만드는 훌륭한 모듈입니다. 이 모듈은 APL, Haskell 및 SML의 구성 요소에서 영감을 받은 반복기 빌딩 블록을 구현하며 각각은 파이썬에 적합한 형태로 재 작성되었습니다.

먼가 말이 어렵습니다.  itertools 를 통해서 데이터 조작을 편하게 해보자는 야그겠지요. 그것이 무엇인가 반복되는 요소에 대한 처리일 경우 말이죠. 개발자는 코드로 말하기 때문에 바로 코드 예로 들어갑니다.


패키지 임포트

import itertools

itertools 를 임포트 합니다.


chain()

letters = ['a', 'b', 'c', 'd', 'e', 'f']
booleans = [1, 0, 1, 0, 0, 1]
decimals = [0.1, 0.7, 0.4, 0.4, 0.5]

print list(itertools.chain(letters, booleans, decimals))

결과 : ['a', 'b', 'c', 'd', 'e', 'f', 1, 0, 1, 0, 0, 1, 0.1, 0.7, 0.4, 0.4, 0.5]

설명:  간단히 말하면 리스트( lists/tuples/iterables ) 를 연결하는 것이다.


count()

from itertools import count , izip
for number, letter in izip(count(0, 10), ['a', 'b', 'c', 'd', 'e']):
print '{0}: {1}'.format(number, letter)

결과:

0: a  10: b  20: c  30: d  40: e

설명:  
count 는 반복하고자 하는 최대수를 미리 알지 않아도 되는 경우 사용됩니다. 여기서는 0 에서 시작해서 10씩 5개의 요소에 대해서 필요한 만큼 증가시켜 주고 있네요.  간단하게 말해서 시작과 step 만 있는 range 함수 느낌도 납니다. 


izip 

from itertools import izip

print list(izip([1, 2, 3], ['a', 'b', 'c']))

#  결과 : [(1, 'a'), (2, 'b'), (3, 'c')]

설명:  
파이썬에서는 이미 요소를 튜플에 결합하는 zip () 함수가 표준 라이브러리에 있으며 거의 같은 방식으로 작동하지만 약간의 성능 향상을 위해 iterable 객체를 반환합니다. 

imap


from itertools import imap

print list(imap(lambda x: x * x, xrange(10)))
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

설명:  
파이썬에서는 이미 요소를 튜플에 결합하는 map () 함수가 표준 라이브러리에 있으며 거의 같은 방식으로 작동

xrange() 이야기 - 홍민희님 블로그의  Python 제너레이터+반복자의 마법에서 발췌

Python은 Haskell처럼 모든 인자가 지연 평가되는 언어는 아니지만 워낙 모든 함수가 반복자를 주고 받게 되어 있다보니 반복자의 연쇄가 깊게 이뤄진다. 반복자의 연쇄가 깊다는 것은 함수 호출 스택이 깊어도 맨 끝에서 아래까지 “의도”1가 잘 전달된다는 뜻이다. 예를 들어 아래의 코드를 보자.

odd_numbers_to_10 = itertools.takewhile(lambda i: i <= 10, (x for x in xrange(1000) if x % 2))

너무나 작위적인 예제지만, 의도가 깊게 관통하는 코드의 예로서는 읽을만 하다. 결국 최종적으로는 “0 이상 10 이하의 홀수 목록”을 원하는 건데, 최초로 제공되는 소스인 xrange(1000)은 10을 초과하는 숫자는 생성하지 않는다. 의도가 잘 전달된다는 것은 이러한 뜻이다. 의도가 전달되지 않는 예를 만드려면 xrange range로 바꾸면 된다.2

odd_numbers_to_10 = itertools.takewhile(lambda i: i <= 10, (x for x in range(1000) if x % 2))

이 코드는 최종적으로 얻고자 하는 값이 결국 10 이하의 숫자들뿐임에도 range(1000)이 1000개의 수가 담긴 큰 리스트를 만들어내는도록 냅둔다. 공간도 낭비고 시간도 낭비다. 만약 우리가 xrange(1000) range(1000) 자리에 무한개의 숫자를 만들어내는 함수를 넣는다면 결정적인 차이가 발생한다. 만약 그 함수가 반복자를 반환한다면 우리가 처음 xrange(1000)을 썼던 코드와 효율에 차이가 없겠지만, 리스트를 만들어낸다면 리스트를 만들다가 메모리가 꽉 차서 뻗고 말 것이다.


islice 

from itertools import islice

for i in islice(range(10), 5):
print i

#  결과 : 0 4   |
# 설명 : [0 ~ 10] 의 반복가능 객체에서 5번째 안으로 짤라라

for i in islice(range(100), 0, 100, 10):
print i

#  결과 : 0 10 20 30 40 50 60 70 80 90  
# 설명 : islice () 함수는 slice () 함수와 동일하게 작동합니다. 첫 번째 매개 변수는 반복 가능한 객체이고, 두 번째 매개 변수는 시작 색인입니다. 세 번째 매개 변수는 끝 색인입니다. 마지막 매개 변수는 각 반복 후에 건너 뛸 수있는 단계 또는 숫자입니다. 


tee

from itertools import tee

i1, i2, i3 = tee(xrange(10), 3)
print i1
# <itertools.tee object at 0x2a1fc68>
print list(i1)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print list(i1)
# []
print list(i2)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print list(i2)
# []
print list(i3)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print list(i3)
# []

설명:

tee () 함수는 두 개의 매개 변수를 사용합니다. 첫 번째는 반복 가능이며 두 번째는 만들고자하는 복사본 갯수입니다. 예제를 보시다시피 한번 사용된 레퍼런스는 더 이상 값을 참조 하지 않습니다. 

r = (x for x in range(10) if x < 6)
print r
# <generator object <genexpr> at 0x2a22870>
i1, i2, i3 = tee(r, 3)
print list(r)
# [0, 1, 2, 3, 4, 5]
print list(i1)
# []
print list(i2)
# []
print list(i3)
# []

설명:

이렇게 원본의 제네레이터인 r 을 실행시키면 나머지 복제본들도 다 참조가 끊어 지는 특성이 있습니다.


cycle

from itertools import cycle , izip
for number, letter in izip(cycle(range(2)), ['a', 'b', 'c', 'd', 'e']):
print '{0}: {1}'.format(number, letter)
# 0: a
# 1: b
# 0: c
# 1: d
# 0: e

설명:

순환 가능한 객체에서 요소를 반복적으로 생성합니다. count 는 계속 증가하구요. 둘 모두 함께 계산되어지는 오른쪽 리스트에 따라 한정지어지는 특성을 지녔습니다.


repeat

from itertools import repeat
print list(repeat('Hello, world!', 3))
# ['Hello, world!', 'Hello, world!', 'Hello, world!']

설명:  요소를 반복합니다. 반복되는 갯수를 지정 합니다.


dropwhile

from itertools import dropwhile
print list(dropwhile(lambda x: x < 10, [1, 4, 6, 7, 11, 34, 66, 100, 1]))
# [11, 34, 66, 100, 1]

설명:  필터링 함수중 하나로서,  10보다 큰것이 나올 때까지 모든 요소는 드랍시키고 나머지것을 리턴함. 


takewhile

from itertools import takewhile
print list(takewhile(lambda x: x < 10, [1, 4, 6, 7, 11, 34, 66, 100, 1]))
# [1, 4, 6, 7]

설명:  필터링 함수중 하나로서,  10보다 큰 것이 나올때까지의 모든 요소를 리턴함. 


ifilter

from itertools import ifilter
print list(ifilter(lambda x: x < 10, [1, 4, 6, 7, 11, 34, 66, 100, 1]))
# [1, 4, 6, 7, 1]

설명:  필터링 함수중 하나로서,  10보다 작은 모든것을 리턴함. 


groupby


from operator import itemgetter
from itertools import groupby

attempts = [
('dan', 87),
('erik', 95),
('jason', 79),
('erik', 97),
('dan', 100)
]

# Sort the list by name for groupby
attempts.sort(key=itemgetter(0))

# Create a dictionary such that name: scores_list
print {key: sorted(map(itemgetter(1), value)) for key, value in groupby(attempts, key=itemgetter(0))}
# {'dan': [87, 100], 'jason': [79], 'erik': [95, 97]}

설명:  key 함수로 itemgetter(0) 를 이용하여 정렬후,  첫번째 요소로 groupby 함.  (정렬해야함)

from collections import defaultdict

counts = defaultdict(list)
attempts = [('dan', 87), ('erik', 95), ('jason', 79), ('erik', 97), ('dan', 100)]

for (name, score) in attempts:
counts[name].append(score)

print counts
# defaultdict(<type 'list'>, {'dan': [87, 100], 'jason': [79], 'erik': [95, 97]})

설명:  defaultdict 사용. 널값에 대한 체크를 생략할 수 있는 편의 제공. 



레퍼런스:

https://www.blog.pythonlibrary.org/2016/04/20/python-201-an-intro-to-itertools/

http://programeveryday.com/post/using-python-itertools-to-save-memory/




내 블로그에 이런 글들을 써서 올려야겠다라고 생각했었는데.. 다음 같은 싸이트가 있더라..

번역이 좀 딱딱한 면이 있어서..다시 작성 할 생각도 있으며 
멀티쓰레드,멀티프로세스,동시성 부분만 추가하고 싶은 생각도 든다.

중급자들을 위한 파이썬 

차례:



# coding=utf-8
import time
import datetime

# 2017-08-30 21:21:57.860000
def getCurrentTime():
return datetime.datetime.now()

# 초를 문자열 시간으로
def getCurrentTimeBySec(s):
m = s / 60
timestr = "2016-05-19 {}:{}".format(m / 60, m%60)
print timestr
return datetime.datetime.strptime(timestr, "%Y-%m-%d %H:%M")


# 시간 차이를 문자열로 00:00:03
# tTime datetime 타입이 들어간다.
def getDiffTimeToTime(dtTime) :
return getCurrentTime() - dtTime

# 1502108747.22 같은 누적초로 리턴
def getCurrentClock() :
return time.time()

# time.struct_time(tm_year=2017, tm_mon=8, tm_mday=7, tm_hour=21, tm_min=36, tm_sec=9, tm_wday=0, tm_yday=219, tm_isdst=0)
def getlocalTime():
return time.localtime()

# 2017-08-07 같이 날짜만 문자열로 리턴
def getCurrentStrDate() :
return time.strftime("%Y-%m-%d")

# 2017-08-07 13:02:00 같이 날짜+시간을 문자열로 리턴
def getCurrentStrTime() :
return time.strftime("%Y-%m-%d %H:%M:%S")

# 2017-08-07 13:07 처럼 분까지만 리턴
def getCurrentStrMinTime() :
return time.strftime("%Y-%m-%d %H:%M" + ":00")

# 2017-08-07 13:02 처럼 현재 시간에서 5분전 시간을 문자열로 리턴
# beforeMin 에는 이전 몇 분이 들어간다. ) getCurrentStrMinTimeAgo(5)
def getCurrentStrMinTimeAgo(beforeMin) :
return (datetime.datetime.now() - datetime.timedelta(minutes=beforeMin)).strftime("%Y-%m-%d %H:%M" + ":00")

# 2017-08-07 21:32:43.407 리턴
def getCurrentStrSecTime() :
t = getCurrentClock()
tmicsec = t - int(t)
return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(t)) + ".{:03d}".format(int(tmicsec * 1000))

# 2017-08-07 21 시간 까지 문자열로 리턴
def getCurrentPowerAllStrTime() :
return time.strftime("%Y-%m-%d %H")

# tTime : 입력된 초
# time.localtime([secs]) 입력된 초를 변환하여, 지방표준시 기준의 struct_time 을 리턴
# time.gmtime([secs]) 입력된 초를 변환하여 , UTC 기준의 STRUCT_TIME 시퀀스 객체 리턴
def getStrTime(tTime) :
return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(tTime))

# tTime 2개의 입력된 초의 차를 초로 리턴
def getDiffTime2(tTime1, tTime2) :
return tTime2 - tTime1


# 현재 초와 tTime 초의 차를 초로 리턴
def getDiffTime(tTime) :
return getCurrentClock() - tTime
# 입력받은 날짜(정수)와 현재 날짜의 날수 차이 def getDiffDay(year,month, day): input_day = datetime.date(year,month,day) today = datetime.date.today() delta = today - input_day return delta.days


# 초를 입력으로 넣은 후에 해당 초에 해당하는 지방표준시의 시퀀스중에 nIdx 번째 값을 리턴한다. 순서는 아래와 같다.
# # time.struct_time(tm_year=2017, tm_mon=8, tm_mday=7, tm_hour=21, tm_min=36, tm_sec=9, tm_wday=0, tm_yday=219, tm_isdst=0)
def getDateTimeFromIndex(tTime, nIdx) :
return time.localtime(tTime)[nIdx]

# 초를 입력으로 넣은 후에 해당 초에 해당하는 지방표준시의 시퀀스들을 리스트로 가져온다..
# # time.struct_time(tm_year=2017, tm_mon=8, tm_mday=7, tm_hour=21, tm_min=36, tm_sec=9, tm_wday=0, tm_yday=219, tm_isdst=0)
def getClockElement(tTime) :
return [
getDateTimeFromIndex(tTime, 0),
getDateTimeFromIndex(tTime, 1),
getDateTimeFromIndex(tTime, 2),
getDateTimeFromIndex(tTime, 3),
getDateTimeFromIndex(tTime, 4),
getDateTimeFromIndex(tTime, 5)
]


# datetime 객체를 입력받아서 누적초로 리턴한다. 1502109843.0
def getTimeFromDateTime(dtTime) :
return time.mktime(dtTime.timetuple()) # + dtTime.microsecond / 1E6

# , , 일 을 숫자로 입력 받아서 완성된 누적초로 리턴
def getTimeFromEachValue(nYear, nMonth, nDay) :
return getTimeFromDateTime(datetime.date(nYear, nMonth, nDay))

# 누적초를 입력 받아서
#2017-08-07 21:49:35 같은 datetime.datetime 객체 리턴
def getDateTimeFromTime(tTime) :
return datetime.datetime.fromtimestamp(time.mktime(time.localtime(tTime)))

# 시간 문자열을 입력 받아서
#2017-08-07 21:49:35 같은 datetime.datetime 객체 리턴
def getDateTimeFromString(szTime) :
return datetime.datetime.strptime(szTime, "%Y-%m-%d %H:%M:%S")


#2017-08-07 21:49:35 같은 datetime.datetime 객체에 숫자로 일수를 더한 결과를 datetime 타입으로 리턴
def addDayToDateTime(dtTime, nDay) :
return dtTime + datetime.timedelta(days=nDay)

# datetime 타입을 입력해서 누적초를 리턴
def convertDatetimeToSec(dtTime) :
return dtTime.total_seconds()


time 모듈은 unix epoch time 이후로 초 단위로 취 한 부동 소수점 숫자로 표현 됩니다. datetime 모듈은 많은 동일한 작업을 지원하면서 더 많은 객체 지향 유형 세트를 제공하며 시간대에 대한 제한된 지원도 제공합니다.



Python 의 simplejson 사용하기


의존성 추가 

import simplejson


문자열로 JSON 형태 만들기 

szJson = '{' + '"callid":{}, "nodeid": {}, "content":"{}"'.format(1, 1, "hello") + '}'

이렇게 { "key" : "value"}  식으로 만들 수 있다.

출력해보면 아래와 같다.

print szJson  # {"callid":1,  "nodeid": 1,  "content":"hello world"}

print type(szJson)  # <type 'str'>


문자열 JSON 형태를 JSON Object (사전타입) 로 만들기  

jsonObj = simplejson.loads(szJson)


출력해보면 아래와 같다.  Dictionary (사전) 타입이 되었다. (순서 무시) 

{'content': 'hello world', 'callid': 1, 'nodeid': 1}

<type 'dict'>


사전 타입이기때문에 아래와 같이 사용 할 수 있다. 

print jsonObj["type"]

1 이 출력된다. 즉 문자열을 key/value 로 사용하기 쉽게 바꾸는것일 뿐이다. 


JSON Object (사전타입) 를 문자열 JSON 형태로 만들기  


packet = simplejson.JSONEncoder().encode(
{ "callid": 1,
"nodeid": 1,
"content": "hello world"
}
)

print packet
print type(packet)

아래와 같다.

packet = simplejson.JSONEncoder().encode(jsonObj)

출력해보면 아래와 같다.  다시 문자열이 되었다. 

{"content": "hi", "callid": 1, "nodeid": 1}

<type 'str'>


JSON Object (사전타입) 의 내용 바꾸기 

Dictionary (사전) 타입이기 때문에 그냥 아래와 같이 하면 된다.

jsonObj["content"] = "new hello world"


 

재밌군요. ㅎㅎ 컬렉션 부분만 캡쳐~

http://www.techworm.net/2016/10/learn-entire-python-language-single-image.html 





파이썬으로 클라우드 하고 싶어요  (http://www.slideshare.net/yongho/2011-h3)

2011년 발표니 꽤 된 내용이지만 굉장히 깔끔하게 잘 정리 되 있네요.

최근에 파이썬으로 분산,병렬 컴퓨팅하는 방법에 대해 개인적으로 다시 정리 할 예정이고 아래 대략 메모.


사실 어떻게 보면 굉장히 명쾌하다. 하둡/스파크같은 시스템을 직접 만들려고 하면 어렵지만 ㅎㅎ

확장 순서는 이렇게 될 꺼 같다.  

1. 자신의 컴퓨터에서 단일 프로세스로 자신이 만든 데이터 분석 프로그램을 돌린다.

2. 자신의 컴퓨터에서 멀티쓰레드로 자신이 만든 데이터 분석 프로그램을 돌린다.

3. 자신의 컴퓨터에서 멀티 프로세싱으로 자신이 만든 데이터 분석 프로그램을 여러개 돌린다.

4. 고성능 파이썬등의 책을 참고하든지 최대한 성능을 올릴 수 있는 방안을 찾아보자. (옵션. 추천하지 않음) 

5. 자신의 컴퓨터에서 GPU 를 이용해서 돌린다. (이것도 옵션)

6. 성능좋은 서버에 자신의 프로그램을 복사해 두고 , 삼바같은것으로 연결한 후에 내용을 수동으로 바꿔서 돌린다.

    (즉 자신의 컴퓨터와 서버 n대로 분산되었다) 

7. 이제 자동화 할 타이밍. 각서버에서 돌아갈 프로세스는 동일하지만 옵션이 다를 것이다. 그 옵션을 분리한다.

   - 분리된 옵션을 자신의 PC에서 각각의 서버에서 돌아가는 프로그램에 전달해서 돌린다.

8. 지금 까지는 특정 알고리즘/프로그램 대상으로 자신이 직접 구축한 병렬/분산이었고 , 이제 범용화 할 타이밍이 됬다.

   즉 클라이언트에서 짠 알고리즘을  분산서버에 제출하여 실행하도록 하자.

9. 최신의 자신에 적합한 병렬도구를 찾아보자. 분산도구를 찾아보자.클라우드 도구를 찾아보자.

+ Recent posts