PYTHON

[빅데이터 분석] 2021.12.22 자료구조, 파이썬 스타일 코드

죠으니 2021. 12. 22. 21:33

 

오늘 자습을 많이 한 것 같은데 진도도 많이 나갔네 ㅇㅁㅇ

다음주에 시험을 친다,,오마이갓,,

제발 커트라인은 넘게 해주세요!!!

계속 실행하면서 머리에 넣어야겠당

 

<자료구조>

◇스택에서 데이터의 저장과 추출

스택(stack)은 Last In First Out. 마지막에 들어간 데이터가 가장 먼저 나오는 형태

▶a.append(20)  스택에서 데이터의 저장(push)

☞ 20이 저장됨

▶a.pop()    스택에서 데이터의 추출(pop)

☞ ()안에 아무것도 없으면 맨끝부분에 있는 것을 빼냄

 

◇텍스트 역순 추출

원래 list 순서

['P', 'Y', 'T', 'H', 'O', 'N']

▶result = []
   for _ in range(len(world_list)):
        result.append(world_list.pop())

['N', 'O', 'H', 'T', 'Y', 'P']

☞ 글자수만큼 반복하고 데이터를 하나씩 추가함

☞ for in 사이에 요소가 아무런 의미가 없으므로 _을 씀. i, name 등 _자리에 다른 변수를 써도 되긴 함

▶print(word[::-1]) 역순

NOHTYP

 

◇큐

first in first out 먼저 들어간게 먼저 나온다.

▶a.pop(0)  0번째니깐 처음에 들어간걸 추출한다는 뜻

 

◇튜플과 세트

-튜플은 리스트와 비슷한데 값 변경은 불가능. 튜플의 경우 t = (1,)요소가 하나만 있어도 뒤에 ',' 찍어줘야 됨

-세트의 경우 값을 순서 없이 저장하면서 중복을 불허하는 자료형. 중복은 뺀다. 수학의 집합과 비슷

▶튜플

   t = (1,2,3)

   print(t+t, t*2)

(1, 2, 3, 1, 2, 3) (1, 2, 3, 1, 2, 3)

▶세트

  s = set([1, 2, 3, 1, 2, 3])    출력하면 중괄호{}로 바뀐다.

{1, 2, 3}

▶s.add(4)    세트의 데이터 하나 추가

{1, 2, 3, 4}

▶s.update([1, 4, 5, 6, 7])    세트의 리스트 추가

{1, 2, 3, 4, 5, 6, 7}

▶s.discard(3) 

   s.remove(1)

☞ 세트의 데이터 하나 삭제(삭제하고 싶은 데이터 ()입력하면 됨)

▶s.clear()  세트의 모든 데이터 삭제

 

◇세트의 교집합, 합집합, 차집합

s1 = set([1, 2, 3, 4, 5])
s2 = set([3, 4, 5, 6, 7])

합집합

print(s1.union(s2))
print(s1 | s2)

{1, 2, 3, 4, 5, 6, 7}
{1, 2, 3, 4, 5, 6, 7}

교집합

print(s1.intersection(s2))
print(s1&s2)

{3, 4, 5}
{3, 4, 5}

차집합

print(s1.difference(s2))
print(s1-s2)

{1, 2}
{1, 2}

 

◇딕셔너리

▶딕셔너리 선언

   student_info = {20140012:'Sungchul', 3.2:'Jiyoung', 20140058:'Jaehong'}

▶student_info[20140012]  딕셔너리의 데이터 검색

'Sungchul'

▶student_info['20140015'] = 'Janhyeok'  딕셔너리의 데이터 추가

{20140012: 'Sungchul',
 3.2: 'Jiyoung',
 20140058: 'Jaehong',
 '20140015': 'Janhyeok'}

 

◇딕셔너리의 함수

country_code = {'America':1, 'Korea':82, 'China':86, 'Japan':81}

▶country_code.keys()

dict_keys(['America', 'Korea', 'China', 'Japan'])

▶country_code.values()

dict_values([1, 82, 86, 81])

▶country_code.items()

dict_items([('America', 1), ('Korea', 82), ('China', 86), ('Japan', 81)])

▶for k, v in country_code.items():
    print(k)
    print(v, '\n')  \n 줄바꿈

▶'Korea' in country_code.keys()    in은 요소가 있나, 없나를 알려줌

 

 

<파이썬 스타일 코드>

◇단어 붙이기

colors = ['red', 'blue', 'green', 'yellow']

result = ''
   for s in colors:            일반적인 for문
       result += s
   result

'redbluegreenyellow'

☞  result += s 은 result = result + s 랑 같다

▶파이썬 스타일 코딩 : join 함수 이용

   join은 리스트 값을 결합하여 문자열로 반환해줌

   result = ''.join(colors)   ''이거 사이에 아무것도 없어서 다 붙어서 나오는 것
   result

'redbluegreenyellow'

▶result = ','.join(colors)
  result

'red,blue,green,yellow'

 

◇문자열의 분리 및 결합

split() : 빈칸을 기준으로 문자열 분리하기

   items = 'zero one two three'.split()
   items

['zero', 'one', 'two', 'three']

▶example = 'python,jquuery,javascript'
   example.split(',')                                ',' 기준으로 문자열 나누기

 

['python', 'jquuery', 'javascript']

▶리스트의 각 값을 a, b, c 변수로 언패킹

   a, b, c = example.split(',')
   print(a)
   print(b)
   print(c)

python
jquuery
javascript

 

◇리스트 컴프리헨션

▶result = []
   for i in range(10):
       result.append(i)
또는 

  result = [i for i in range(10)]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

▶필터링 : if문과 함께 사용하는 리스트 컴프리헨션

  짝수만 저장하는 리스트 컴프리헨션

   result = []
   for i in range(10):
       if i%2==0:
           result.append(i)
   result

또는

  result = [i for i in range(10) if i%2==0]

[0, 2, 4, 6, 8]

▶if문을 앞으로 옮겨 else 문과 함께 사용할 수도 있음

   result = [i if i%2==0 else 10 for i in range(10)]

   result

[0, 10, 2, 10, 4, 10, 6, 10, 8, 10]

☞ 짝수인 것은 그대로 쓰고 나머지는 10으로 쓴 것

중첩 반복문

   word_1 = 'Hello'
   word_2 = 'World'

   result = [i+j for i in word_1 for j in word_2]
   result
(5개와 5개를 더하므로 5**2만큼 갯수가 나옴)

['HW',
 'Ho',
 'Hr',
 'Hl',
 'Hd',
 'eW',
 'eo',
 'er',
 'el',
 'ed',
 'lW',
 'lo',
 'lr',
 'll',
 'ld',
 'lW',
 'lo',
 'lr',
 'll',
 'ld',
 'oW',
 'oo',
 'or',
 'ol',
 'od']

이차원 리스트

['The', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog']

   stuff = [[w.upper(), w.lower(), len(w)] for w in words]
   stuff

[['THE', 'the', 3],
 ['QUICK', 'quick', 5],
 ['BROWN', 'brown', 5],
 ['FOX', 'fox', 3],
 ['JUMPS', 'jumps', 5],
 ['OVER', 'over', 4],
 ['THE', 'the', 3],
 ['LAZY', 'lazy', 4],
 ['DOG', 'dog', 3]]

대괄호가 두개 있으니 이차원이다

 

◇다양한 방식의 리스트, 딕셔너리 출력

enumerate 함수

enumerate는 인덱스(키)와 값을 쌍으로 출력

for i, v in enumerate(['tic', 'tac', 'toe']):
  print(i, v)

0 tic
1 tac
2 toe

리스트값에 인덱스를 붙여 출력

▶딕셔너리에서 인덱스를 로, 단어를 으로 출력

{i:j for i,j in enumerate('TEAMLAB is an academic institute lacated in South Korea.'.split())}

{0: 'TEAMLAB',
 1: 'is',
 2: 'an',
 3: 'academic',
 4: 'institute',
 5: 'lacated',
 6: 'in',
 7: 'South',
 8: 'Korea.'}

Zip 함수

▶리스트 값을 병렬로 묶어 출력

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

   for a, b in zip(alist, blist):
       print(a, b)

a1 b1
a2 b2
a3 b3

같은 위치에 있는 리스트 값끼리 더하기

   a, b, c = zip((1,2,3), (10,20,30), (100,200,300))

   print(a, b, c)

(1, 10, 100) (2, 20, 200) (3, 30, 300)

[sum(x) for x in zip((1,2,3), (10,20,30), (100,200,300))]

[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)

0 a1 b1
1 a2 b2
2 a3 b3

 

<람다 함수>

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

◇람다 함수의 다양한 형태

▶f = lambda x : x**2
   f(3)

▶f = lambda x : x/2
   f(3)

 

◇맵 리듀스

map 함수 : 연속 데이터를 저장하는 시퀀스 자료형에서 요소마다 같은 기능을 적용할 때 사용

▶ex = [1,2,3,4,5]
   f = lambda x : x**2

   list(map(f, ex))      리스트 ex의 각 요소에 함수 f를 적용하여 다시 리스트로 받기

[1, 4, 9, 16, 25]

제너레이터 : 시퀀스 자료형 데이터를 처리할 때 실행 시점의 값을 생성하여 효율적으로 메모리 관리
   for문인데 메모리를 효율적으로 쓰는 for문이라고 생각하면 됨

  리스트 없이 map 함수를 사용하는 경우(제너레이터 개념)

   ex = [1,2,3,4,5]
   f = lambda x : x**2

   for value in map(f, ex):
       print(value)

최근에는 람다 함수나 map 함수보다 리스트 컴프리헨션을 권장한다.

map 함수는 입력값으로 여러 개의 시퀀스 자료형을 받을 수 있다.

   ex = [1,2,3,4,5]
   f = lambda x , y : x+y
   list(map(f, ex, ex))

[2, 4, 6, 8, 10]

리스트 컴프리헨션으로도 해결 가능

   [x+y for x,y in zip(ex, ex)]

[2, 4, 6, 8, 10]

map 함수의 필터링 기능. 즉  if 쓴다는 것

   list(map(lambda x:x**2 if x%2==0 else x, ex))

[1, 4, 3, 16, 5]

☞ 'lambda x:x**2 if x%2==0 else x'은 lambda함수다.

☞ ex 각 요소마다 lambda 함수를 적용한다.  짝수는 제곱으로 나오고 홀수는 그냥 나온다

리스트 컴프리헨션으로 구현하면 더 간단

   [x**2 if x%2==0 else x for x in ex]

1부터 5까지 정수를 더하는 함수
   for y in [1,2,3,4,5]:
       x += y

15

▶reduce 함수 : 리스트 같은 시퀀스 자료형에 차례대로 함수를 적용하여 모든 값을 통합하는 함수 

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

 

◇별표의 사용

*(asterisk) : 별표

  1. 곱하기, 제곱할때 쓴다
  2. 가변인수-함수의 가변인수를 사용할 때 변수명 앞에 별표를 붙인다

가변 인수

   def asterisk_test(a, *args):
      print(a, args)
      print(type(args))
    
   asterisk_test(1,2,3,4,5,6)  1은 변수 a에, (2,3,4,5,6)은 변수 args에 할당됨

1 (2, 3, 4, 5, 6)
<class '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)    b,c,d,e,f,가 딕셔너리 형태로 들어가게 됨

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

▶별표의 언패킹 기능

변수 앞에 별표를 붙이면 여러 개의 변수를 한 번에 넣을 수 있는 컨테이너 역할을 함

   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 가 튜플 변수를 언패킹하여 받은 것

 

◇선형대수학(linear algebra)

벡터의 연산

▶기본적인 for문을 사용한 벡터 덧셈

   u = [2,2]
   v = [2,3]
   z = [3,5]

   result = []
   for i in range(len(u)):
       result.append(u[i] + v[i] + z[i])

   result

[7, 10]

zip함수, 리스트 컴프리헨션을 이용한 벡터 덧셈

result = [sum(t) for t in zip(u,v,z)]
result

[7, 10]

▶변수가 많은 경우 : 별표를 사용한 함수화  -> 여러 가지 변수를 받을 수 있다.

   def vector_addition(*args):
       return [sum(t) for t in zip(*args)]

   vector_addition(u,v,z)

[7, 10]

 

스칼라-벡터 연산

 

백터크기방향을 모두 가지는 것

스칼라크기만 가지는 것

벡터 u,v  방향성이 있다는 것은 위치값이 있다는 것
   u = [1,2,3]
   v = [4,4,4]

   alpha = 2  스칼라 alpha

   # 스칼라-벡터 연산
   result = [alpha*sum(t) for t in zip(u,v)]    zip을 쓰면 같은 위치 값끼지 엮인다
   result                                              두개를 더하고 곱하기 2한 값이 나옴

[10, 12, 14]

list(zip(u,v))        zip함수는 앞에 list해줘야 됨

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

행렬의 연산

▶matrix_a = [[3,6], [4,5]]

  matrix_b = [[5,8], [6,7]]

   result = [[sum(row) for row in zip(*t)] for t in zip(matrix_a, matrix_b)]
   result

[[8, 14], [10, 12]]

전치 행렬(transpose matrix)

numpy array로 변환 후 적용. 행열이 바뀜

  matrix_a = [[1,2,3], [4,5,6]]

 

   import numpy as np
   np.array(matrix_a).T

array([[1, 4],
       [2, 5],
       [3, 6]])

행렬 곱(내적) :dot product

데이터에 가중치를 구할 때 행렬곱을 쓴다

▶matrix_a = [[1,1,2], [2,1,1]]

   matrix_a = np.array(matrix_a)

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

▶matrix_b = [[1,1], [2,1], [1,3]]

   matrix_b = np.array(matrix_b)

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

▶np.dot(matrix_a, matrix_b)

array([[5, 8],
       [5, 6]])