IT/언어

[python] 머신러닝을 위한 Python(2)

개발자 두더지 2020. 6. 3. 23:21
728x90

1. Pythonic Code - Enumerate & Zip

1) Enumerate

List의 element를 추출할 때 인덱스도 함께 추출하는 방법
# list에 있는 index 값을 unpacking ; i에는 index번호가, v에는 list의 요소가 대입됨
for i, v in enumerate(['tic', 'tac', 'toc']):
    print(i,v)
>> 0 tic
   1 tac
   2 toc

# 응용 (1) : list의 index와 값을 unpacking하여 list로 저장
mylist = ["a", "b", "c", "d"]
newlist = list(enumerate(mylist))
print(newlist)
>> [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]

# 응용 (2) : 문장에서 각각의 단어들의 위치를 뽑을 때도 유용, 문장을 list로 만들도 list의 index와 값을 unpacking하여 dict로 저장
newlist = {i:j for i,j in enumerate('Gachon University is an academic institute located in South Korea.'.split())}
print(newlist)
>> {0: 'Gachon', 1: 'University', 2: 'is', 3: 'an', 4: 'academic', 5: 'institute', 6: 'located', 7: 'in', 8: 'South', 9: 'Korea.'}

 

2) Zip

두 개의 list의 값(같은 인덱스에 위치한 값)을 병렬적으로 추출할 때 사용,벡터 계산에 유용하게 사용가능
# 병렬적으로 값을 추출
alist = ['a1', 'a2', 'a3']
blist = ['b1', 'b2', 'b3']
for a, b in zip(alist,blist):
  print(a,b)
>> a1 b1
   a2 b2
   a3 b3

# 응용(1) : 각 tuple의 같은 index끼리 묶음
a, b, c = zip((1,2,3),(10,20,30),(100,200,300))
print (a, b, c)

# 응용(2) : 같은 index의 합 구하기 
new = [sum(x) for x in zip ((1,2,3), (10,20,30), (100,200,300))] # x에 tuple 형태로 저장됨에 모든 요소의 합을 구함
print(new)
>> [111, 222, 333]

물론 Enumerate와 Zip을 함께 사용할 수 있다.

alist = ['a1', 'a2', 'a3']
blist = ['b1', 'b2', 'b3']

for i, (a,b) in enumerate(zip(alist, blist)):
    print(i, a, b) # index alist[index] blist[index]표시

>> 0 a1 b1
   1 a2 b2
   2 a3 b3

2. Pythonic Code - Lambda & MapReduce

1) Lambda

함수 이름 없이, 함수처럼 쓸 수 있는 익명의 함수를 Lambda라고 한다.
General function Lambda function

def f(x,y):
return x+y
print(f(1,4))

f = lambda x,y : x+y
print(f(1, 4))

앞서 배운 list comperhesion에 의해 Python3에서 부터는 권장하지는 않으나, Pandas에서 효율적으로 사용할 수 있는 부분들이 있기 때문에 개념은 알아두는 것이 좋다.

print((lambda x: x+1)(5))
>> 6

 

2) Map 함수

Map 함수는 Sequence 자료형(예: list )의 각 element에 동일한 function을 적용하는 것이다.

Lamdba 함수와 잘 사용하는데, 역시 Python3에서 권장하지 않는다. 

map(function_name, list_data)

 map과 lambda함수를 같이 적용한 예는 아래와 같다. 참고로 Python2에서는 map 출력시 list를 작성 안 해줘도 원하는대로 값이 출력되지만, Python3에서는 map 출력시 list를 붙여서 작성해줘야 값이 출력된다.

(Python3에서 list를 작성하지 않으면 단순히 map의 메모리 위치가 출력된다.)

ex = [1,2,3,4,5]
f = lambda x: x**2
print(list(map(f, ex)))
>> [1, 4, 9, 16, 25]

# zip 처럼 사용할 수도 있다.
ex = [1, 2, 3, 4, 5]
f = lambda x,y : x+y
print(list(map(f, ex, ex)))
>> [2, 4, 6, 8, 10]

참고로 list를 붙이지 않아도 for문을 이용해서 요소 값을 출력할 수 있다.

ex = [1, 2, 3, 4, 5]
f = lambda x: x**2
print(map(f, ex))
for i in map(f, ex):
    print(i)

>> 1
   4
   9
   16
   25

lambda 함수에서도 필터를 적용할 수 있는데, 주의해야 할 점은 반드시 else부분도 작성해줘야 한다.

ex = [1, 2, 3, 4, 5]
print(list(map(lambda x: x**2 if x % 2 == 0 else x, ex)))
>> [1, 4, 3, 16, 5]

 

3) Reduce 함수

map 함수와 달리 list에 똑같은 함수를 적용해서 통합

사용하기 위해서는 fuctools에서 reduce함수를 import해야 한다. Sequence자료형의 각각의 요소에서 옆으로 이동하면서 적용되는 함수를 Reduce 함수라고 한다.

from functools import reduce
print(reduce(lambda x,y: x+y, [1,2,3,4,5]))
>> 15

따라서 팩토리얼 계산도 Reduce함수로 쉽게 구할 수 있다.

from functools import reduce

def factorial(n):
    return reduce(
        lambda x,y: x*y, range(1, n+1) # range에서 알아서 1~5까지의 값 생성
    )

print(factorial(5))
>> 120

3. Pythonic Code - Asterisk

 

여기에서는 단순 곱셈, 제곱연산, 가변인자 활용 등 여러 부분에서 다양하게 사용되는 Asterisk(*)의 사용법을 알아본다.

1) 인자로 사용

*args **kargs

def asterisk_test(a, *args):
    print(a, args)
    print(type(args))

asterisk_test(1, 2, 3, 4, 5, 6)

>> 1 (2, 3, 4, 5, 6)
<class 'tuple'>

# 한 번의 여러 개의 변수를 함수에 넘겨 줄 때 asterisk사용 (가변인자) ; 첫 번째 인자는 a로 들어나고 나머지 요소들은 args에 tuple형태로 저장됨

def asterisk_test(a, **kargs): 
    print(a, kargs)
    print(type(kargs))

asterisk_test(1, b=2, c=3, d=4, e=5, f=6)

>> 1 {'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6}
<class 'dict'>

# 키워드 인자로 변수를 넘겨줄 때 사용, dict형태로 저장된다.

 

2) unpacking a container

- tuple, dict 등 자료형에 들어가 있는 값을 unpacking

- 함수의 입력값, zip 등에 유용하게 사용 가능

def asterisk_test(a, *args):
    print(a, args)
    print(type(args))

asterisk_test(1,*(2,3,4,5,6))

>> 1 (2, 3, 4, 5, 6)
<class 'tuple'>

def asterisk_test(a, args): 
    print(a, *args)
    print(type(args))

asterisk_test(1,(2,3,4,5,6))

>> 1 2 3 4 5 6
<class 'tuple'>

# args에 하나의 element로 삽입되었지만 print문의 *args에 의해 unpacking되어 여러 개의 element가 삽입되어 졌다.

a, b, c = ([1,2], [3,4], [5,6])
print(a, b, c)

data = ([1,2],[3,4],[5,6])
print(*data)

>> [1, 2] [3, 4] [5, 6]
   [1, 2] [3, 4] [5, 6]
def asterisk_test(a, b, c, d):
    print(a, b, c, d)

data = {"b":1, "c":2, "d": 3}
asterisk_test(10, **data)

>> 10 1 2 3
for data in zip(*([1,2],[3,4],[5,6])):
    print(data)

>> (1, 3, 5)
   (2, 4, 6)

참고자료

https://www.edwith.org/aipython/lecture/22954/

https://www.edwith.org/aipython/lecture/22955/

https://www.edwith.org/aipython/lecture/22956/

728x90