Numpy는 파이썬을 위한 과학 컴퓨팅 기본 패키지다.

리스트나 다른 배열과의 차이점은 넘파이 배열은 같은 타입만 요소를 가질 수 있다. 즉 동종(Homogenous type)만 요소로 있을 수 있다. 예를 들어, float32면, float32끼리만 요소로 가질 수 있고, int16이면 int16끼리만 가질 수 있다. 넘파이 배열은 보통 ndarray라고 부르는데, 앞서 언급한것처럼 내장 라이브러리에 array와는 다르다. 

 

Numpy객체들을 ndarray라고하는데, 이 객체가 가지고 있는 속성들은 다음과 같다.

- ndarray.ndim: 축의 개수를 출력(=차원의 수)

- ndarray.shape: 배열의 크기를 출력

- ndarray.size: 배열이 가지고 있는 총 요소의 수를 의미한다. 예를 들어 (3,2)의 모양을 가지고 있는 배열의 경우 6이 출력된다.

- ndarray.dtype: 데이터 타입 (형변환은 ndarray.astype()으로 변환)

- ndarray.itemsize: 배열의 각 요소의 바이트 단위의 사이즈. 즉 dtype에서 정의한 타입을 바이트 단위로 출력한다. 

float 64는 나누기 8을 하면되니, itemsize 8이 출력된다. 

 

 

 

 

Nd.arrayDtype: Nan(not a number)데이터타입은실수형(float)으로분류가된다. Integer바꿀, nan있으면못바꿀있다.

itemsize

retype.itemszie: 바이트 단위 사이즈 

 

int는 4byte.

 

long형은 8bytp여서 +_921경

3대는 int와 long의 구분이 없고, int의 자리수의 길이의 제한이 없어서... 그래서 대량 데이터는 최대길이의 숫자에 맞춰서 알아서 메모리를 할당하기 때문에, 공간의 낭비가 심하다.

numpy에서는 적당한 int32, int64 알아서 잡아서 할당해준다.

 

100도 안넘는데도 불구하고, 16가 나을것같은데 32를... 컴퓨터는 4바이트 단위로 짤라서 쓸 때, 속도가 가장빠른데, 32를 기준으로한다. 대부분의 언어도 그렇다.

 

 

dtype의 이해


항목 하나하는 64bit로 늘려서 만드는게 아니고, 두 항목을 64bit로 묶어서, 반환을 한다. 그래서 아래와 같이 이상한 값이 나온다.

32bit가 2개가 모여서 64bit가 되는거여서, 엉뚱한 값이 나온다. 타입의 용량이 부족하다고 맘대로 64bit로 늘리면 안된다.

왜냐하면 타입의 변경할 때, 실제 저장된 데이터의 구조(비트)가 변경되어서 반환이 되기 때문이다. 

Windows시스템의 특성 때문에, 그렇다. 이 는 숫자를 저장할 때, 비트 순서를 뒤바꾸어서 저장을 한다. 0+1을 결합해서 나오는데, 1과 0이 숫자가 뒤바뀌어서 나온다. 

 

예를 들어, 000000000 000000000.  000000000 000000000 <-0

000000000 000000000.  000000000 00000001 <- 1 이다.

이것을 합칠 때,  0다음에 1을 넣는게 아니라 1을 먼저 앞으로 두고, 0을 넣는다. (상위비트와 하위비트를 바꾸어서 저장하도록 되어있다) 만일 64비트 1을 저장한다면, 스텍의 크기 때문에, 먼저 저장한걸 나중에 저장하기 때문에,CPU구조 때문에 16bit->32bit 32비트씩 끊어서 저장을 하게되는데, 예를 순서대로 집어넣으면 반대로 나오기 때문에 뒤짚어서 저장을 한다. 

 

1
2
3
a.dtype = np.int64
# 원래32인 것을, int64로 바꾸면, 엉뚱한 값이 나온다
# 항목 하나 하나를 int64로 바꾸라는 말이 아니라, 전체 a를 int64로 바꾸라는 말로 된다.
cs
 
 
 
배열을 만들기

 

 

 

 

 

 

 


1. array을 통해 만들기.

 

arrary을 통해서 만들꺼면, array()함수 내에 시퀀스형을 넣어야한다. 시퀀스형은 예를 들어서, 튜플이나 리스트 등을 입력값으로 해야 넘파이객체가 만들어진다.

 

 

 

1
2
3
4
5
6
7
8
9
10
# array함수를 이용해서 만들기 
= np.array([2,3,4]) # 타입도 알아서 지정된다.
= np.array([2,3,5.4]) # type: float64
# Complex type
= np.array([[12], [34]), dtype = complex) # 복소수로 만든다.  1 + 0.j
# 기존의 배열을 가지고 만드는 경우
= np.array(c)
id(c), id(d) # id 주소가 서로 다름.
d2 = np.arrary(c, copy=False) # 새로운 배열을 만드는게 아니라, 주소를 그대로 쓸 수 있음.
 
cs

 

 

 

2.기본값 있는 배열 만들기

 

np.zeros(), np.ones(), np.empty()의 세가지 함수를 이용해서 만들 수 있다. 

np.array()는 안에 스퀀스형이 인자로 들어갔지만, 기본값이 있는 배열은 변수에 크기를 입력하면된다.

이렇게 만들어진 배열은 64비트인데, 타입 지정시 속도가 조금씩 차이가 난다.

타입을 지정할 때, 속도도 고려할 수 있는데, 정수는 4바이트 단위가 빨라서 32비트가 빠르다

실수는 64비트가 빠르다. 실수의 표현방법은 IEEE 954-9규약에 부동소수점 표현방법에 따라서 기본적으로, 실수는 64비트로 실수로 계산하게끔 만들어놓아서 32비트면 잘라서 해야되서 64비트가 빠르다.

1
2
3
4
5
6
7
8
9
10
11
np.ones((3,4))
# 정수는 4바이트가 빠르고
# 실수형은 64비트가 빠르다. 
 
np.empty((3,4))
np.arange(10# 1차원으로 반환
np.arange(5,10# 5부터 10미만
np.arage(5203# range(5,20,3)과 같다.
 
# 실수단위로 단위로, 개수를 지정하여 출력하기 위해서
np.linspace(029# 0부터 2까지 9개를 뽑아주세요. (0, 0.25, 0.5, 0.75....2) 마지막 값을 뽑아준다 
cs

3. 연속된 값을 갖는 배열 만들기.

numpy.arange(start, stop, step, dtype=None)

np.arange()을 이용해서 생성하는 방법이다. range()와 유사하게 사용할 수 있다.

또는 np.linespace(start, stop, num= 갯수) 을 이용해서도 출력할 수 있다.

1
2
3
import numpy as np
np.linspace(010, num=10)
np.linspace(02*3.14100
cs

 

 

 

 

배열의 차원 변경하기


np.random.random((3, 4))을 이용해서, (3,4) shape의 랜덤으로 배열을 만들 수 있다.

배열의 차원을 변경하는 함수들은 바로 반환되는게 아니라서, 다시 객체를 리턴값으로 받아주는 할당문이 있어야한다. 

 

np.ravel(): 차원이 모두 풀린 배열을 반환

1
2
= np.floor(10*np.random.random((3,4)))
a.ravel() # 차원이 풀린 1차원으로 배열을 나열한다.
cs

 

np.T: 전치행렬(transpose)을 반환

np.reshape(shape): (x,y) 의 shape을 가진 배열로 변경. 요소의 수(=size)가 같아야 한다. reshape(3,-1) 처럼 shape의 형태가 -1인 경우, 차원의 크기는 앞에 맞춰서 자동으로 계산이 된다. 

np.resize(shape): reshape이랑 같은 기능을 가진 메서드이다. 

 

resize와 reshape의 차이는?

reshape은 그 배열을 바꾸지 못하고, 리턴만해주는데, resize는 배열 자체를 변경한다.

reshape은 -1을 사용가능하지만, resize는 -1을 사용하지 못한다.

1
2
3
4
5
6
7
8
9
>>> import numpy as np
>>> a = np.arange(0,10)
>>> a.reshape(2,5)
>>> print(a)
[0 1 2 3 4 5 6 7 8 9]
>>> a.resize(2,5)
>>> print(a)
[[0 1 2 3 4]
 [5 6 7 8 9]]
cs

 

 

 

 

 

1
2
3
4
5
6
7
= np.arange(24).reshape(2,3,4# axis = 0 열임, 마지막 축은 '깊이가 2개인 행렬'
 
np.set_printoption(threshold=1000# 1000개까지만 출력하게 만듬
np.aragne(1010).reshape(10,101# 1000개가 나오고 10개가 가려지는게 아니라. 그보다 훨씬 더 많이 안보임
 
 
 
cs

Numpy 배열의 연산


행렬의 곱연산은 *이 아니라 dot 또는 @을 이용하여 계산한다. *으로 할 경우, 요소별 연산(element-wise)연산이 되기 때문에 다르다.

 

보통, 행렬을 연산할때, 피연산자의 shape이 다른 경우에는 브로드캐스팅 규칙이 적용되는데, 복합대행연산자(바로 대입하는 연산)를 이용할때는 타입이 같아야한다(라인 16~23). 복합대행연산자는 중간에 객체를 또 만들지 않고, 기존의 배열을 수정하기위해 사용된다. 
그러나, 아래의 예시처럼, a가 int형이고, b가 기본형(기본 dtype= float64)인 경우에는 풀어서 연산을 다시 할당받으면 사용 에러가나지 않고, int가 float32또는 float64의 형태로 상향형변환(upcasting)되지만, 복합대행연산자를 이용하여 할당받으려면, 객체의 타입이 그대로 int인 상태에서 연산이 float형을 받아야하기 때문에(=downcasting)이 되지 않아 에러가 발생한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
b**2 # 각 요소들을 제곱
a<35 # boolean으로 출력
np.sin(a) # 요소별로 사인값을 출력
 
 
# 곱연산
= np.array([[11], [13]])
= np.array([[20], [34]])
A*# Asterik을 쓰면안되고, 각 요소별로 곱이 나온다. 
 
# 행렬의 곱
np.dot(A,B)
A @ B 
 
# 복합대입연산자
= np.ones((2,3), dtype=int)
*= 3
 
= np.random.random((23)) # dtype = float64임.
 
= b + a # float64가 포함할 수 있지만
= b + a # int 을 포함할 수는 없지만, 풀어쓰면 가능하다. a+b을 더해서 실수를 만들어놓고, 추후에 a를 변환
+= b # 안된다. Down casting이 불가능하다. 1:1로 매핑하면서 계산을 해가는데, 동종모음이다보니깐 출력이 안됨
 
cs

 

 

Numpy Axis & Aggregation


넘파이 객체를 쓰다보면, 집계를 해야하는 경우가 있는데, 이럴 때 마다 ,축이 너무 헷갈려서 어느 축에 대해서 연산을 해야할지 모르는 경우가 발생한다. 이럴 때, 축에 대한 의미를 조금 더 공부할 필요가 있다. 

 

간단히 요약하면, axis = 0 은 로우를 하나로 보고 합치는 연산(row-wise)을 의미하고, aixs =1 은 컬럼을 하나로 봐서, 합치는 연산(column-wise)을 의미한다.

numpy의 axis을 어떤축을 합칠 것인지(collapses)를 말해주는 것이다. 

아래의 예시를 보면서 설명을 해보자.

 

1
2
3
4
5
6
>>> b = np.arange(12).reshape(3,4)
>>> print(b.shape)
>>> print(b)
>>> b.sum(axis=0# [12, 15, 18, 21]
>>> b.sum(axis=1# [6,22,38]
>>> b.sum(axis=2# Error
cs

 

 

위의 예를 보면 b의 shape이 (3, 4)인데, axis=0은 기본적으로 shape에서 가장 왼쪽에 있는 축을 의미한다고 생각하면 된다. 따라서 axis=0은 (,4)가 나와야한다고 생각하면 연산의 결과를 이해하기 쉽다. 따라서 요소가 4개가 나와야하니, 열(columns) 별로 연산을 한다고 생각하면 된다(라인4). 반대로, axis=1은 shape의 두번쨰인 (3,)이므로 3개가 나오면 된다고 생각하면되므로, 행별로 연산을 한다고 생각하면된다. 물론 ndim(차원의수)가 2개이니 axis 2는 불가능하다(에러, axis는 0축부터 시작하기 때문). 즉, axis 축이 가르키고있는 shape 숫자와 같은 결과가 출력된다. 

 

1
2
3
4
= np.aragne(24).reshape(2,3,4)
= sum(axis=0# dim 2. except 2 shape, aggregation result (3,4)
= sum(axis=1# dim 3. except 3 shape, aggregation result (2,4)
= sum(axis=2# dim 3, except 4 shape, aggregation result (2,3)
cs

 

 

 

범용함수 


 

1
2
3
4
5
6
7
# python general function
x1 = add(x1, x2)
x1 = np.arange(12).reshape(3,4)
x2 = np.arange(12).reshape(3,4)
x3 = x1 + x2 # 누산기를 통한 합계
add(x1, x2, x1)  # equivalent to 1 line (누산기X)
x1 += x2 # equivalent to 1 line (누산기X
cs

 

 

 

브로드케스팅 & 엘리먼트와이즈


브로드 케스팅 규칙은 '연산의 두 배열에 대한 후미 축의 크기가 동일한 크기이거나 둘 중 하나가 1이어야 한다는 것'이다. 예를 들어, (1, 3)과 (1,1)은 후미축의 크기가 동일하지는 않지만, 후미축이 1이므로 연산값을 동일하게 반복하여, 계산할 수 있다. 라인 6번~9번이 이에대한 설명이다. 그러나, 1) 반대로 후미축의 크기가 1이 아니거나, 2) 연산할 배열의 후미축이 다른경우는 라인 11번과같이 에러가 발생할 수 있다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# element wise
= np.array([1,2,3])
= np.array([2,2,3])
+ b
 
# Braodcasting
= np.array([1,2,3]) 
= 2 # scala varible 
+ b
 
# Error
= np.array([1,2,3])
= np.array([1,2])
 
 
cs

 

아래의 예시에서도 1번~7번라인처럼 a.shape = (3, 3)이고 b가 (3, 3)이기 때문에 해당 연산이 가능하다. 또한 10번~라인부터처럼 a의 후미축의 크기가 1이고, b의 후미축의 크기가 1이 경우에도 해당 연산이 가능하다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import numpy as np
 
= np.array([[000],
              [123],
               [234]) # shape = (3,3)
= np.array([1,2,3]) # shape = (1,3)
+ b # last dimensions of both variables are equal
 
 
# Broadcasting is possible if dimension of any variabels is 1
from numpy import array, newaxis
= array([0,1,2,3,4])
= array([1,3,2]) 
print(a.shape, b.shape) # (5,), (3,)
print(a[:, newaxis].shape) (5,1)
a[:, newaxis] + b ; 
cs

 

 

 

인덱싱 & 슬라이싱


판다스의 인덱싱과 슬라이싱처럼, 넘파이에서 인덱싱과 슬라이싱이 가능하다. 이를 통해, 할 수 있는 것은, 배열에서의 부분집합을 추출하는 것이다. 리스트와 마찬가지 인덱싱은 0번부터 인덱스가 시작한다. 음수를 적용한 슬라이싱/인덱싱 도 리스트와 동일하다. 

 

차원별 인덱스하는 방법이 조금씩 다른데, 1차원에서는  np.array[0축], 2차원에서는 np.arrary[1축, 0축], 3차원에서는 np.array[2축, 1축, 0축]으로 지정하여 추출할 수 있다. 

 

한편, 축인덱스를 생략해서 출력할 수 있는데, 예들 들어서, 차원의 수가 3이경우에, a[-1] 과 같이하면, a[-1::]와 동일하다.

1
2
3
4
5
6
>>> import numpy as np
>>> a = np.arange(24).reshape(2,3,4)
>>> a[-1::]
array([[[12131415],
        [16171819],
        [20212223]]])
cs

 

'...'을 이용해서 인덱스를 생략할수도 있다.  

1
2
3
4
5
6
# a[:,:,2] vs  a[::2] 비교
>>> print(a)
a[0::] # 2축에 대해서 시작이 0, 맨 뒤까지 뽑겠단 코드
a[::2# 2추게 대해서, 시작이 0, 2step 단위로
a[0,:,:] # 2축에 대해서 0번인덱스이고 모든 인덱스를 포함한 서브셋을 출력
a[0,...]
cs

 

 

 

Stack

 


축에 대한 이해가 필요하다.  종류로는 hstack, vstack, dstack 이 있다. hstack은 옆으로 쌓는 것이기 때문에 0축의 개수가 늘어나며, vstack은 아래에 row을 하나 더 붙이는 것이기에, 1축의 개수가 늘어난다. dstack은 dimension이 늘어나는것인데, (3, 4)짜리 2개를 nstack하면 (3, 3, 4)의 모양의 배열이 출력된다.

 

vstack:

hstack

nstack: 첫 번째 배열의 0번과 두 번째 배열의 0번을 조합하여 하나의 마지막 축에 해당하는 요소를 하나 더 늘린다.

stack((넘파이배열, 넘파이배열, 넘파이배열...), axis = 축): axis에 따라 범용으로 사용

축에 대한 파라미터가 없으면, 0축으로 합쳐진다.  (3,4) shape인 2개의 넘파이가 0축을 기준으로 합쳐지면 (2,3,4)가 된다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# hstack: 배열을 옆에 추가하는 방식. horizontal 옆으로 쌓는다
= np.arange(3)
= np.arange(3,6)
 
np.hstack((a,b)) #
print(np.hstack((a,b)).shape) # (6,)
# vstack
np.vstack((a,b)) 
print(np.vstack((a,b)).shape) # (2,3)
# dstack: 깊이별로 쌓는다. 차원이 하나 증가한다. '[]' 대괄호가 증가한다
np.dstack((a,b))
print(np.dstack((a,b)).shape) # (1,3,2)
 
# newaxis
# 1차원이 newaxis을하면 2차원이 되고, 
# 2차원이 newaxis을하면 3차원이 된다.
= a[:, np.newaxis]
= b[:, np.newaxis]
np.hstack((a,b))
cs

 

 

dstack은 같은 배열에서, 0축이 2배로 증가하는 것과 같다. 

 또한, 축에 숫자를 넣을 때, 축의 숫자는 shape에서 순서가 변하는 것과 같다. (3, 4)의 2개의 배열이 합쳐질 때, axis = 0이면, shape의 첫요소 2가 되어서 (2,3,4)이며, axis =1이면 (3,2,4)가 되며, axis =2 이면 (3,4,2)가 된다.

 

r_(), c()

r_(): R에서의 rbind와 유사하다.

c_(): R에서의 cbind와 유사하다 .

 
1
2
3
4
5
6
7
8
9
10
11
import numpy as np
= np.array((1,2,3,4)) # shape (4,)
= np.array((5,6,7,8))
= np.array((9,10,11,12))
 
# r_()
np.r_[a,b,c] # R bind와 유사하게, 길이를 늘려준다. shape (12,)
np.r_[[a],[b],[c]] # 리스트로 구분하고 싶다면..
np.vstack((a,b,c)) # vstack과 동일
print(a.shape, b.shape, c.shape) # (4,) 을 vstack하면 (3,4)
print(np.vstack((a,b,c)).shape) # (3,4)
cs

 

 

Split

split은 array 배열을 받아서, 리스트로 반환한다.split은 n개로 나누어서 나머지가 0이 아니면 에러가 나온다.

  • hsplit: 0축을 기준으로 나누어 반환함. hsplit 은 split(~, axis=1)과 같다. 두 번째 shape을 기준으로 잘라서 나온다. 2, 3, 4를 자르면 (2,1,4)가 출력됨.
  • vsplit: 가장 맨 앞의 shape 기준으로 나누어서 반환함. (3, 4)을 split하면 (1,4)가 요소인 배열이 나옴. split(~, axis=0). (2,3,4)을 2로 나누면 (1,2,4)가 나온다.
1
2
3
4
5
6
7
8
# Split
= np.arange(12).reshape(3,4)
print(a)
 
# np.vsplit
a_vsplit = np.vsplit(a, 3# (3,4) shape짜리를 vertical로 붙여준다.
print('shape:', a_vsplit[0].shape) # (1,4)가 3개, (4,)이 3개가 아님.
 
# np.hsplit 
a_hsplit = np.hsplit(a, 4) # (3,4) shape짜리를 4개로 쪼개어
print('shape:', a_hsplit[0].shape) # (3,1)이 4개
cs

 

3차원으로 확장하면, 다음과 같다.

 

튜플형식으로 나누자고하면, 다음과같다

예를 들어, hsplit (2,5,6)은 0~1까지 하나, 2~4까지하나 5~6에서하나 6부터 끝까지 출력된다.

 

 

  • Numpy.array_split(array, num_section, axis = 0)

 

 

split은 나눠 떨어지지 않으면, 오류가 나온다. 그러나, 나눠 떨어지지 않는 정수를 이용하여, 배열을 분리한다.

SQL에의 NTILE처럼, n개로 나눈후에 나눈 나머지는 앞에서부터 순차적으로 가져간다. 예를 들어 13개를 3개로 나누면, 5, 4, 4개로 나누어진다.

 

 

 

 

 

데이터복사(View, Copy)


Numpy.view() = 동일 주소값의 데이터 + 형태만 다른 배열 객체

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

같은 데이터를 참조하지만, 다른 shape을 가지는 객체를 의미한다. 데이터 자체는 처음 뷰를 생성한 객체가 가지고 있다. 예를 들어 a를 통해서 뷰를 생성한 경우에는 shape은 다르게 가질 수 있다. 데이터의 부분집합을 추출할 때, view을 뽑을지, copy로 뽑을지 고민해야한다. copy와 view의 차이점은 copy는 완전히 메모리상에 완전히 새로운 데이터를 갖는다 (주소값이 다르다). 뷰는 메모리상에 같은 데이터를 참조를 하지만, 다만 shape가 다르기 때문에, 읽는 순서가 달라질 뿐이다. (= 깊은 복사 , copy) 

뷰를 통한 shape은 다르게 가질 수 있다.

 

 

파이썬이 [1, 2, 3] 을 저장할 때, 1은 따로 저장, 2도 따로저장, 3도 따로 저장한다음에, 1의 주소 2의 주소 3의주소 이렇게 연결자료구조로 만든다. 그러나 numpy 차원 배열을 저장할 때는 np.array([1,2,3], type = int32)처럼 숫자가 크기를 고려해서 저장하기 때문에, [1][2][3] 연결해서 32비트씩을 가져서 한개의 값을 인덱싱을할 때 바로 알 수 있다. 첫 주소만 알면 나머지는 변수의 자료의 크기만큼만 건너 뛰면되기 때문에, 바로 알 수 있다.

 

인덱싱할 때, 배열로 뽑아올 경우는 copy가 온다.

 

 

 

고급인덱싱를 이용한 인덱싱


 

1
2
3
4
5
6
7
8
# 리스트 배열로 인덱싱
= np.arange(12)**2
ind = np.array([1,1,3,8,5])
a[ind] # array([ 1,  1,  9, 64, 25])
 
# 다차원으로 만들기
= np.array([[3,4], [9,7]])
a[j]
cs

 

다차원 인덱싱


인덱싱 자체가 여라차원인 경우를 의미한다. X[Y, Z] 이러한 인덱싱에,  Y도 다차원, Z도 다차원을 사용하는 경우를 의미한다.

이러한 인덱싱은 X[Y,:]을 우선 계산한다음에, X[Y. :]에 Z인덱싱을 적용한다. 아래의 예시를 보면 이해가 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 다차원 인덱싱
import numpy as np
= np.arange(12).reshape(3,4)
= np.array([[0,1], [1,2]])
= np.array([[2,1], [3,3]])
 
 
a[i,:] 
# array([[[ 0,  1,  2,  3],
#         [ 4,  5,  6,  7]],
 
#        [[ 4,  5,  6,  7],
#         [ 8,  9, 10, 11]]])
# 위의 조건에서 j을 적용한다. 즉 a[i,:]에서 2번째 컬럼을 찾고, 1번쨰 컬럼, 
3번쨰 컬럼, 3번째 컬럼을 찾는다
 
a[i,j]
# array([[ 2,  5],
#        [ 7, 11]])
cs

 

 

최대값 검색

 

 

 

 

 

 


np.argmax : 최대값을 갖는 인덱스를 찾는다.

 

 

 

 

 

 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 배열 인덱스를 이용한 최대값 검색
import numpy as np
data = np.sin(np.arange(20)).reshape(5,4)
# array([[ 0.        ,  0.84147098,  0.90929743,  0.14112001],
#        [-0.7568025 , -0.95892427, -0.2794155 ,  0.6569866 ],
#        [ 0.98935825,  0.41211849, -0.54402111, -0.99999021],
#        [-0.53657292,  0.42016704,  0.99060736,  0.65028784],
#        [-0.28790332, -0.96139749, -0.75098725,  0.14987721]])
 
ind = data.argmax(axis=0)
# array([2, 0, 3, 1])
 
# 이렇게 복잡하게 해야하는데.
data_max = data[ind, range(data.shape[1])]
range(data.shape[1])
 
# 아래의 경우처럼 바로 찾는 것도 가능하다.
data.max(axis=0)
cs

 

 

 

인덱싱을 이용한 값 변경


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# --인덱스를 이용한 값 변경--
import numpy as np
 
= np.arange(5)
a[[1,3,4]] = 0 # 인덱스를 이용한 값 변경
# a[1,2] # 1,2 을 넣으면 a를 2차원으로 인식해서 shape 1,2 인덱스를 찾는다.
a[[1,2]] # [1,2] 을 넣어야한다.
 
= np.arange(5)
# [0 1 2 3 4]
 
 
a[[0,0,2]] = [10,20,30# 0번째 인덱스는 20이 할당
a[[0,0,2]] += 1 # 가장 마지막 값만 변경된다.  #[1,1,3,3,4]
# a[[0,2]] 만 실행이 된다.
cs

 

 

 

논리 배열 인덱스를 이용한 인덱싱


 

1
2
3
4
5
# 부울 배열을 이용한 인덱싱 (True / False을 이용한 인덱싱)
= np.arange(20).reshape((4,5))
= a% 2 ==0 # 나누기 2가 0인 경우만 true가 반환하다. 
a[b] = a[b] **2 # 재할당도 가능하다
a[b] = 0 
cs

 

 

ix_()


1
2
3
4
5
6
7
8
9
10
# ix_() 
= np.array([2,3,4,5])
= np.array([8,5,4])
ax, bx = np.ix_(a,b) # N개의 1차원 시퀀스를 입력 받아 추출해서 ,
각각 N차원인 N 개의 출력을 반환
 
# (array([[2],
#        [3],
#        [4],
#        [5]]), array([[8, 5, 4]]))
 
cs

 

 

 

 

리듀서(Reducer)


집계하는 함수를 모두 리듀서라고 부름(reducer). 매개변수로 함수와 값들을 입력받아 각 요소들에 함수를 적용하고 하나의 결과의 값을 반환하는 함수

1
2
3
4
5
6
7
8
9
10
# 집계하는 함수를 모두 리듀서라고 부름(reducer)
def func_reduce(*vectors, func=np.add):
    vs = np.ix_(*vectors)
    r = func.identity # 항등원을 계산
    print(vs)
    for v in vs:
        r = func(r, v)
    return r
 
func_reduce(a,b)
cs

 

배열 조작


- 행렬 곱: @ 또는 dot

- 역행렬 np.linalg.inv(x)

- 특이값 분해: u, s, vh = np.linalg.svd(A)

- 고유값, 고유벡터 = w, v = np.linalg.eig(x)

 

원본행렬 A(m, n)를 쪼개서 U라는 행렬과 sigma라는 대각행렬 V(t) ㅍ

(m, m) (m, n), (n, n) 이 반환. 원본행렬을 가장 잘 표현할 수 있는 왼쪽상단. 오른쪽 하단으로 갈 수록 원본행렬을 표현하기에는 대표적이지 않은 값일 수 있음. Sigma 행렬을 그래서 다 사용하지 않고, 일부를 잘라서 사용한다.

원본행렬이 null 이 너무 많은 경우, 특이값 분해를 한 다음에, 다시 원본행렬을 만들면 null이 채워지는 경우가 있다.

 

선형 연립방정식


역행렬을 구하려면 정방행렬을 만들어야하는데, 행의수가 열의수가 훨씬 많을 때, left pseudo inverse 을 구한다.

 

히스토그램 

히스토그램 구간내의 값만 알려준다.

 

 

 

dtype


unsigned int8

np.fromstring()

 

 

 


np.power: np.power은 흔히 멱급수를 따른다고하는 식으로 반환한다. 쉽게설명하면 np.power(a, b)은 a**b와 같다.

np.power(10, 2) # 100
np.power(3, 2)  # 9
np.power(9, 0.5) # 3.0

First array elements raised to powers from second array, element-wise.

Raise each base in x1 to the positionally-corresponding power in x2. x1 and x2 must be broadcastable to the same shape. Note that an integer type raised to a negative integer power will raise a ValueError.

 

Parametersx1array_like

The bases.

x2array_like

The exponents. If x1.shape != x2.shape, they must be broadcastable to a common shape (which becomes the shape of the output).

반응형

'Data science > Python' 카테고리의 다른 글

0. Python 이란?: 언어형태, 특징, 메모리관리  (0) 2019.06.16
python 시각화 : Seaborn  (0) 2019.06.10
Python 시각화: 기본  (0) 2019.05.30
2. Python: function  (0) 2019.03.19
1. 기본자료형, Python Built-in Code  (0) 2019.03.05


print("{1} {0} {owner} blog".format("this", "is", owner="lemoncandy's"))



본글에서는 파이썬의 기본 자료형(문자열, 논리, 기본연산자 등)을 다루고, 이에 대한 예시를 들어 독자의 설명을 돕고자합니다.




파이썬 & 객체


파이썬의 중요한 특징 중 하나는, 객체 모델이다. 숫자, 문자열, 자료구조, 함수, 클레스, 모듈은 모두 파이썬 객체라는 것으로, 객체라는 것에 저장된다. 이 객체에 해다하는 자료구조들에 대한 것만 살펴보도록한다. 파이썬의 자료구조는 크게 4가지로 분류할 수 있는데, 문자열(String), 리스트(List), Tuple(튜플), 사전(dictionary)에 해당된다. 추가하자면 파일 등을 덧붙일 수 있을 것 같다.


아래는 파이썬 내장 자료형에 대한, 내장함수와 기본적으로 알아야할 부분에 대한 오버뷰이다. 해당 내용중에 모르는 것이 있으면 자료구조를 더 이해하는 것이 바람직하다.



Python 내장 자료형 (요약)

  1. String: "" or ''으로 묶여진 문자의 모임
    1. Indexing
    2. Slicing : [Start index: Stop index : Step] 파이썬 2.3부터 지원
    1. immutable: 문자열은 중간 값이 변경되지 않는다
    2. Membership test
  2. List
    1. List offset:
    2. 순서있음
    3. List length
    4. List slicing
    5. List 
    6. List 덧셈
    7. 확장 슬라이스
    8. Membership test
    9. Append
    10. del
    11. L.reverse() : 리버스하면 바로 리스트가 변경된체로 저장되어진다.
    12. L.sort(): 리버스와 마찬가지로, 정렬된 리스트가 변수에 담겨진다.
  3. Tuple
    1. indexing: 순서가 있다.
    2. Slicing
    3. 연결: 리스트와 똑같이 +으로 연결한다
    1. Membership test
    2. immutable
  4. Dictionary
    1. Key vs offset
    2. 순서
    3. Membership test
    4. mutable
    5. dic.keys() : 사전의 키만 추출
    6. dic.values() : 사전의 값만 추출
    7. dic.tiems(): 키와 값을 엮어서 리스트로 출력한다.

자료 저장 방법에 따른 자료형의 분류

직접 자료형 

직접 자료를 표현하는 자료형

정수, 실수, 롱형 정수 

시퀀스 형

다른 자료를 포함하는 자료형

(순서를 가진다 = 인덱싱 및 슬라이싱이 가능하다)

리스트, 튜플, 문자열 

매핑 형다른 자료를 포함하는 자료형 
(순서를 가지지 않는다)
딕셔너리 


자료 변경 가능성에 따른 자료의 분류


변경가능(Immutable) 

자료의 값을 변경할 수 있다. 

dic, list 

변경 불가능(Immutable)

자료의 값을 변경할 수 없다. 

수치형, 문자열, 튜플 



자료 변경 가능성에 따른 자료의 분류


 자료형저장 변경 가능성 기타 

수치형(int)

리터럴 (한 가지 종류의 데이터만 저장가능)

변경 불가 

직접 접근 (주소값으로)

문자열(str)리터럴변경 불가 시퀀스 

리스트(list)

저장 가능

변경 가능 

시퀀스

튜플(tuple)저장 가능변경 불가 시퀀스 
사전(dict)저장 가능변경 가능 매핑 

시퀀스자료는 여러 개의 항목 값들이 순서대로 모여 있는 자료형을 순차자료라고한다. 튜플, 리스트, 문자열은 모두 순차자료에 해당된다. (사전은 순차자료가 아니다, 그렇기 때문에 사전에다가 [1]을 붙여서 인덱싱하려고해도 안되는 것이다.) 

직접접근(주소값)에 대한 이해,
예를 들어, 아래와 같은 a, b에 할당이 있다고 하자. a는 'hello my world'을 의 주소값을 가르키고 있기 때문에 문자형이고, b도 문자형이다. 그러나, a가 가르키고 있는 주소와 b가 가르키고 있는 형태가만 같을 뿐, 주소가 다르기 때문에, 3번의 결과와 4번의 결과가 차이가 난다. 아래의 예제를 통해 할 수 있는 것은 문자열은 직접접근하는 형태가 아니라, 주소의 형태로 접근한다는 것을 알 수이싿.
1
2
3
4
= 'hello my world'
= 'hello my world'
print(a==b) # true
print(a is b) # false
cs


        파이썬 자료형의 확인

        자료형을 지정하는 예약어를 사용하여 확인한다.

        1
        type(123== int
        cs



        String Object & Method


        문자열의 슬라이싱과 인덱싱

        문자열 종류의 자료형은 문자열과 슬라이싱은 잘 설명되어 있는 사이트가 있어, 참조를 바란다. [https://wikidocs.net/2838]. 음수인덱싱을 하는 경우가 있어 해당 인덱싱만 설명한다.


        음수 인덱싱

        string[시작인덱싱:-음수]: 인 경우에는 음수 -1 은 뒤에서 역순으로 2번째 문자를 의미한다. 예를 들어, 문자 abcd가 있는 경우, a[-1]은 d를 가르킨다. 그러나, 범위로 슬라이싱을 하는 경우에는 맨 끝의 위치에 해당하는 인덱스를 제외한 결과를 출력하므로 a[0:-1]은 abc을 출력한다. 반대로 a[::-1]은 순서를 거꾸로 해달라는 경우이므로, 역순으로 출력된다. 역순으로 출력되는 경우는 

        1
        2
        3
        = 'abcd'
        print(a[-1])
        print(a[0:-1])
        cs





        str.split(separator, maxsplit): 

         -separator: 나누고자 하는 구분자

         -max split: 최대로 나누고자하는 숫자. 만약 3이면 출력물은 3개는 분리되고, 나머지 1개는 그대로인 상태로 총 길이라 4개인 리스트가 나온다. 즉, 3개까지만 분리를하고 나머지는 그냥 쭉 이어서 배출한다.


        1
        2
        3
        4
        5
        6
        7
        8
        9
        >>> syntax = 'separator : The is a delimiter. The string splits at this specified separator. If is not provided then any white space is a separator. \
        >>> maxsplit : It is a number, which tells us to split the string into maximum of provided number of times. If it is not provided then there is no limit.'
        >>> syntax.split(' ',3)
         
         
        ['separator',
         ':',
         'The',
         'is a delimiter. The string splits at this specified separator. If is not provided then any white space is a separator. maxsplit : It is a number, which tells us to split the string into maximum of provided number of times. If it is not provided then there is no limit.']
        cs


        str.upper()

        str.lower()

        str.count(): 문자열에서 함수 안에 부분 문자열이 있는 횟수를 리턴

        str.find(): 문자열에서 함수 안에 있는 부분 문자열의 offset(시작인덱스)를 리턴

        str.find(like, 3): 문자열에서 함수 안에 있는 like의 offset(시작인덱스)를 3번 인덱스부터 탐색

        s.rfind(): find의 reverse. 뒤에서부터 검색한다.

        s.index(): find와 같다. offset을 리턴한다.

        s.rindex(): index와 같으나, 뒤에서 부터 검색한다.

        s.startswith(): 함수내에의 부분문자열로 시작하는 스트링인지 T/F 리턴

        s.endswith(): 함수내의 부분문자열로 끝나는 스트링인지 리턴

        s.startswith('like',7): 7번 문자열이 like로 시작하는가

        s.replace(원래문자, 바꿀문자)

        str.strip(): 좌우 공백을 없앤다.

        str.rstrip(): 우측 공백을 제거

        str.lstrip(): 좌측 공백을 제거

        str.splitlines(): 라인 단위로 분리

        ':'.joint(t):  ':' 문자로 결합. t = list형태, 

        u.center(): 전체 문자를 x개로 만들고, 문자를 가운데 위치시킨다.

        1
        2
        3
        >>> string = "spoon and egg race"
        >>> string.center(60'-')
        '---------------------spoon and egg race---------------------'
        cs

        str.ljust(): 전체문자를 x개로 만들고, 문자를 왼쪽에 위치시킨다.

        str.rjust(): 전체문자를 x개로 만들고, 문자를 우측에 위치시킨다.

        str.isdigit()

        str.isalph():

        str.isalnu(): 숫자 혹은 영문자인가?

        str.islower():

        str.isupper():

        str.isspace():

        문자열 내에서 전체 자리수 지정하기

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        = '내용 {0:15}을 전체 자리 15자리로 맞추어 출력합니다'.format("python help")
        print(s) # 우측으로 공백
        = '내용 {a:10}을 전체자리 10자리로 맞추어 출력합니다.'.format(a=13)
        print(k) # 좌측 공백
        = 'hello'
        = '내용 {:3}와 {:10}의 자리수를 각각 맞춥니다'.format(a, 3.14)
        print(s) # 전체 다 나옴
        = '내용 {:<3}와 {:<10}의 자리수를 각각 맞춥니다'.format(a, 3.14)
        print(s) # 둘다 좌측 정렬
        = '내용 {:>3}와 {:>10}의 자리수를 각각 맞춥니다'.format(a, 3.14)
        print(s) # 둘다 우측 정렬
        = '내용 {:^10}와 {:^10}의 자리수를 각각 맞춥니다'.format(a, 3.14)
        print(s) # 둘다 중앙 정렬
        = '내용 {:!<10}와 {:*^10}의 자리수를 각각 맞춥니다'.format(a, 3.14)
        print(s) # 빈공간을 !로 
        = '''숫자 {0:.4f}와 {1:0.4f}의 소수점 이하 자리수를 
        4자리 까지만 표현합니다'''.format(3.143259485734.32184)
        print(s)
         
         
        cs


        str.replace(원래문자, 바꿀문자)

        1
        2
        3
        4
        s1 = "Hello my name is Hong kil-dong"
        s2 = s1.replace("Hong"'Kim')
        print(s1)
        print(s2)
        cs



        List Method



        Min, Max

        1
        min(my_list), max(my_list)
        cs


        -추가 관련 함수

        List.append: 마지막에 추가해서 바로 변경됨. (Inplace =True)

        List.insert(index, object): 자료를 지정된 위치(object)에 삽입. (Inplace =True). 해당하는 index에 위치시킨다.

        1
        2
        list_data = ['apple''banana''cherry']
        list_data.insert(2'abc')
        cs



        -인덱스 관련 함수

        List.index(value ,start, stop, position) : return first index of value. 

         - value = 찾을 패턴

         - start, stop = 시작 인덱스, 마지막 인덱스. 즉 범위를 지정할 수 있다.

        1
        2
        3
        4
        5
        ref = [56'abc'7'apple']
        >>> print(ref)
        [56'abc'7'apple']
        >>> ref.index('abc'15)
        2
        cs



        List.extend(value): 변수값 뒤에 리스트를 붙여준다.

        1
        2
        3
        4
        5
        6
        >>> a = ['abcd']
        >>> b = ['b','bbb']
        >>> print(a.extend(b)) 
        None
        >>> a.extend(b)
        >>> a
        cs

        List.count(value): 자료값의 개수를 카운트



        -정렬 관련 함수

        List.reverse(): 인덱스 순서를 반대로 돌려놓고, 저장시킴. 리턴 값 없음

        List.sort(): 값의 순서대로 돌려놓고, 저장함. 리턴 값 없음

        sorted(): 이는 범용함수이다. 리턴 해주고, 저장은 안함


        -삭제 관련 함수

        List.clear(): 리스트의 모든 항목을 제거

        List.del()

        List.remove(value): 리스트 원소중 value인 원소 맨 처음 원소 삭제

        List.pop(index): 마지막의 요소를 리턴하고, 리스트에서 바로 제거

        >>> s.pop(0): 가장 뒤에 있는 요소를 꺼낸다.


        리스트의 슬라이싱

        1
        2
        list_data[-1:-5:1# 라면 start가 end보다 커서 안나옴
        list_data[-1:-7:-1# 스텝이 마이너스이면 나오지만
        cs



        List Comprehension(리스트 내장)

        [Expression for exp1 in sequence 1

                         for exp2 in sequnce 2....]


        10보다 작은 정수 중 홀수의 제곱만 리턴한다.

        >>> [k for k in range(0,10) if k%2 ==1]


        2의 배수와 3의 배수중 두수의 합이 7의 배수가되는 두수의 곱의 리스트를 만든다.

        List comprehension 작성시, expression부분이 튜플일 경우 꼭 활호로 감싸야한다.


        >>>[(i, j) for i in range(0, 100, 2) \

            for j in range(0, 100,3 ) if (i+j) %7 ==0]


        Range()

        # 순차적인 값을 할당할 때 사용한다.

        >>> a, b, c, d = range(0,4)


        None 이 포함된 리스트 생성

        1
        2
        3
        4
        #내용 없는 리스트 생성
        = [None] *10
        for i in range(0,10,2):
            L[i] = i
        cs


        리스트로 2차원 배열 표현

        1
        2
        3
        #리스트로 2차원 배열 표현
        = [ [1,2,3],[4,5,6],[7,8,9]]
        L[2][2]
        cs


        리스트의 슬라이스

        *리스트를 슬라이스 할 때, 리스트[시작인덱스:마지막인덱스:단계] 의 구문으로 한다. 단계(step)을 이요한 슬라이드를 하는 경우 이를 확장슬라이드(extended slice)라고한다. 주의할 것은 확장슬라이드를 이용하여 변수를 치환할 경우 무조건 좌측의 확장슬라이드 값과 우측의 확장 슬라이드의 값이 동일해야한다.

        1
        2
        my_list = list(range(0,10))
        my_list[::3= list(range(5,9))
        cs





        파이썬 함수와 메소드


        적용하고자 하는 변수에 바로 저장이되는 경우 메소드가 많고, 그렇지 않으면 함수인 경우가 많다. 함수는 범용적으로 사용하는 경우가 많은데, 예를 들어서. len()과 같은 함수는 list.len()을 사용하지 않고 모든 자료에 대해서 len(List), len(string)등 다양한 자료형을 커버할 수 있기에 함수이다. 즉, 해당 객체만 사용할 수 있는 경우는 메소드라고 생각하면 편하며, 다양한 객체에 대해서 사용할 수있다면 함수라고 이해하면 된다.


        산술연산
        몫 (/)

        정수형 연산. 결과는 실수형:  9/5

        실수형 연산. 결과는 실수형:  9.0 / 5.0 

        실수형 연산. 결과는 몫만: 9.0 //5.0 

        나머지 (%)

        >>> 9 % 5. 4

        >>> divmod(9, 5)

        reutrn (1, 4)



        파이썬 예약어

        >>> import keyword

        >>> keyword.keylist


        연속라인의 표시

        \

         

        문자열로 된 파이썬 코드의 실행

        eval (expression[, globals[, locals]]): 파이썬에 사용되고 있는 식(expression)을 실행

        >>> a = 4

        >>> a = eval('a+4')

        >>> print(a)

        8


        exec code [ in globals [, locals]] : 문자열로 된 문(statment)을 수행

        >>> a = 5

        >>> exec 'a = a+4'

        >>> a

        9


        compile (string, filename, kind): 코드를 반복적으로 수행할 때, 컴파일 일하여 파이썬 코드를 리턴

        1
        2
        3
        4
        >>> code = compile ('a+1''<string>''eval')
        >>> a= 1
        >>> for k in range(10):
             a = eval(code)

        cs

        Console 입출력

        pprint


        1
        2
        3
        >>> import pprint 
        >>> pprint.pprint(변수명)
         

        cs



        enumerate(): 

        인덱스 값도 같이 필요한 경우 사용하는 함수. (인덱스, 요소 값) 튜플 자료로 반복적으로 넘겨준다.

        1
        2
        3
        = ['cat''dog','bird''pig','spam']
        for k, animal in enumerate(L):
            print(k, animal)
        cs










        Tuple


        튜플의 + 연산

        1
        2
        = (1,2,3)
        t + ('adsl','adsp')
        (1, 2, 3, 'adsl', 'adsp')
        cs



        튜플: 변경 불가능(immutable)


        튜플 패킹(Tuple packing): 튜플안에 어려 종류의 데이터를 보관

        >>> t = 1,2, 'hello'


        튜플 언패킹(Tuple unpacking): 튜플에서 데이터를 꺼내오는 것

        >>> x, y, z = t  (튜플에 x,y,z을 할당)


        리스트와 튜플의 차이

        리스트와의 차이

        메소드를 가지지 않는다.


        튜플을 사용하는 경우

        1) 함수에서 리턴을 2개 이상할 때, 튜플로 묶어서 리턴

        2) 문자열 포매팅

        1
        print('id: {}, name: {}'.format('kkk','jjjj'))
        cs

        3) 튜플에 있는 값을 함수의 인수로 사용할 때

        1
        2
        args=(4,5)
        calc(*args)
        cs

        4) 그외 고정된 값을 표현하기 위해







        Dictionary


        Key 와 value을 이용한 자료형식 구조이다. 

        Key에는 문자, 논리, 튜플, 대소문자를 구별해서 같은 글자를 넣을 수 있다. 완전히 대소문자까지 똑같이 입력할 수는 없다. DISTICT해야한다.

        한편, Value는 딕셔너리, 문자 , 논리, 리스트를 사용할 수 있으면 중복이되어도 상관이 없다. 위에서 key을 이용하였기 때문에, 자료의 순서가 없다. 따라서, 자료의 순서를 이용해서 입출력을 하는 append, extend, insert의 함수를 사용할 수 없다. 단, pop은 key을 인자로 제공한다면, 사용할 수는 있다.


        Dic.items(): (key,value)을 리턴

        Dic.get('key')

        Dic.setdefault('key', 'value'): key가 없으면, 키/값을 새로 만들어준다.

        Dic.popitem(): list의 pop과 동일

        key in D: 멤머십테스트 D가 key을 가지고 있으면 True

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
        25
        # keys, values 출력
        my_dic = {'fruit':'apple''number':1'sport':'golf'}
        print('-'*20"keys")
        for fav in my_dic:
            print(fav)
        #---------------------------
        for fav in my_dic.keys():
            print(fav)
        #---------------------------
        print('-'*20"values")
        for value in my_dic.values():
            print(value)
        #---------------------------
        print('-'*20"items")
        for pair in my_dic.items():
            print(pair)
            
        # Key의 중복
        dict_data2 = {1:'hello'0:'World', True:'Nice'}
        len(dict_data2) # 1이 True 여서 중복으로 하나만 들어간다. 마지막 원소로 덮어쓴다
        dict_data2[3= {'abc'}
        dict_data2['False'= 'zzzzz'
        print(dict_data2)
         
         
        cs


        위의 예제에서, key의 중복을 보면, True와 1은 동일한데 삽입된다. 그렇지만, 1이 True이기고, 앞에서부터 순차적으로 저장한다고 생각한다면 1이 덮어씌워져서 True(1)이 들어가고 그에대한 value로 nice가 입력되게 된다.



        Dictionary의 중복

        딕셔너리는 데이터를 참조할 때 주의해야하는 사항이 있는데, 파이썬은 바로 스텍구조의 자료형에 값을 갖지 않고, 객체를 가지고 주소를 참조한다. 예를 들어서, dictionary2와 dictionary1이 있다고 했을 때, dictionary 1= dictionary2을 하면 같은 각각 객체에 다른 데이터를 가지고 있는게 아니라, 주소가 같아서 같은 데이터를 참조한다. 즉 스텍에 있는 자료구조가 Heap이라는 공간에 값을 할당하여 찾는 구조인데, 주소가 똑같기 때문에 Heap에 자료값이 변경되면, 두 자료모두 변경될 수 있다. 아래의 예제를 통해 확인해보자.




        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        23
        24
         
        d1 ={1:102:10}
        d2 = d1
        print(id(d1), id(d2)) # 주소값이 같다
         
        d2[1= 30 #한쪽만 데이터를 변경한다.
        print(d1, d2) # 그러나, 데이터가 같다.
         
        # 데이터의 변환이 안일어나가 하려면 Copy해야한다.
        # 그러나, Slicing한 경우는 equal 같은 이퀄이 아니라 값이 안바뀐다.
        l1 = [1,2,3,4,5,6,7,8,9,10]
        l2 = l1[0:5]
         
        print(l1, l2)
        del l1[2:6]
        print(l1, l2)
         
        #L
        l1 = [1,2,3,4,5,6,7,8,9,10]
        l2 = l1.copy()
        l1.pop()
        print(l1,l2) # 다르게 출력된다.
         
         
        cs


        위의 예제를보면 list을 Copy하는 경우는 주소값이 따로따로 있기때문에 한쪽 자료를 변경하여도 모두 영향을 받지 않는다. Copy는 리스트나 딕셔러니 구조에서 사용가능하다.


        Set


        Set.issubset(set)

        Set.issuperset(set):

        Set.union(set):

        Set.intersec(set):










        Array module


        Array(typecode [, initializer]): 새 배열을 생성한다.

        typecode에는 i는 Signed integer(최소 2바이트)

        1
        2
        3
        4
        5
        from array import *
        = array('i'range(10)) # 어레이 생성
        a.append(5)
        a.insert(510# 5위치에 10을 입력
        a.extend(array('i',[12,3,4,5])) 
        cs



        디렉토리의 파일 목록 얻기


        OS, glob 패키지

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        #파일의 추가정보를 알아내기
        import os
        import glob
        fileList = glob.glob('*')
        for name in fileList:
            if os.path.isfile(name):
                print('파일')
            elif os.path.isdir(name):
                print('directory')
            elif os.path.islink(name):
                print('link')
        cs




        if 문에서 continue 와 break활용

        1
        2
        3
        4
        for x in range(10):
            if x < 8:
                continue # x <8인 조건을 맞을 떄, 계속 for의 위로 올라간다.
            print(x)
        cs



        Decimal: 계산결과를 10진법으로 오류없이 출력해야하는 경우

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        =0.0
        for k in range(10000):
            e += 0.00001
        print(e) #0.099999939
         
        = Decimal('0.0')
        delta = Decimal('0.00001')
        for k in range(10000):
            e += delta
        print(e) # 0.100000
         
        import math, cmath
        = Decimal('123.567')
        print(math.sqrt(d)) #11.116~
        print(cmath.sqrt(-d)) #11.16.....j
        print(d.sqrt())
        print(d.quantize(Decimal('0.01'), rounding=ROUND_DOWN)) #0.01
        cs


        지수 연산자

        >>> 5 % -3 #파이썬 나머지는 젯수(나누는 값)의 부호와 같다. 5 = -3 * -2 + 1

        >>> --3 # 

        result: 3 -(-3)

        지수연산자는 오른쪽부터 순서대로 계산한다. 따라서, 

        2**3**5와 (2**3)**5의 계산은 다르다.


        관계연산자: >, <, >=, <=








        string type의 관계연산자의 크기비교

        비교시에 길이가 다른 경우도 비교가 가능하다

        >>> 'abcd' > 'abc'

        False

        >>> 'abc' < 'abcd'

        True

        위의 경우에서는 같은 인덱스끼리의 크기 비교를하고, 같으면 다음 순서도 비교를한다. 


        자료형간의 순서

        숫자 < 사전 < 리스트 < 문자열 < 튜플


        boolean으로 논리연산을 판단할 때, 공집합은 무조건 False이고, 아니면 True이다.



        문자열 포맷팅


        %s: 문자열 입력대체할 부분에 '%s' 라고 적은 후, 문장종료(따옴표 종료) 후, %"삽입할 말"을 적는다.

        %d: 정수

        %f: 부동소수

        숫자가 같이 있으면 차지하는 캉을 의미 

        %10s이면 앞에 10칸을 

        %-10오른쪽 

        %0.2f : 소수점 2째자리면 표현됨.

        파이썬 3에서는 str.format지원

        인덱싱도 가능

        print("session:{2}, val:{1}, loss:{0]".format(

        키워드도 가능



        반응형

        'Data science > Python' 카테고리의 다른 글

        0. Python 이란?: 언어형태, 특징, 메모리관리  (0) 2019.06.16
        python 시각화 : Seaborn  (0) 2019.06.10
        Python 시각화: 기본  (0) 2019.05.30
        3. Numpy 한 페이지 요약  (0) 2019.05.13
        2. Python: function  (0) 2019.03.19

        + Recent posts