원래 넘파이랑 판다스는 파이썬을 완전히 끝낸 다음에 포스팅 하려고 했는데 간단한 부분 - (인덱싱이랑 슬라이싱) - 은 먼저 포스팅 하도록 하겠습니다. 코딩은 iPython이 아닌 jupyter notebook에서 작성 했음을 미리 알립니다. 주피터 노트북의 경우 딱 포스트 부분에 맞게 조절하는 방법이 있는 거 같은데 왜 전 안 될 까요ㅠㅠ 아무튼 안 되면 안 되는대로, 딱히 칸을 넘어가는 부분도 없으니까 일단 포스팅 하도록 하겠습니다. 

 

1. 1차원 배열 인덱싱

import numpy as nd

In [2]:

arr = np.arange(10)

In [3]:
arr 
Out[3]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

arange메소드는 설명하지 않았지만 파이썬의 리스트에서 range메서드와

비슷한 역할을 합니다. 따라서 주로 초기화 하는데 저는 사용합니다. 그 외에는 거의 사용하는

적이 없는 것 같습니다.

In [4]:
arr[5] 
Out[4]:
5
In [5]:
arr[5:8] 
Out[5]:
array([5, 6, 7])

1차원 ndarray는 list와 거의 동일하게 동작합니다. 그냥 이 부분에 사용 할 수 있는 메서드가

다르다는 점만 있죠. 주로 많이 사용하는 2차원 ndarray에서 부터 주의가 많이 필요합니다.

In [6]:
arr[5:8] = 12 #색인 영역에 대입한 값이 전파된다. - 브로드캐스팅 
In [7]:
arr 
Out[7]:
array([ 0,  1,  2,  3,  4, 12, 12, 12,  8,  9])

위와 같이 값을 전파 시키는 것을 브로드 캐스팅이라고 합니다. 색인 영역을 잘라서 (슬라이싱) 해서 값을 대입한 후,

이 값을 : 이 후부터 전파시키기 때문에 브로드 캐스팅이라고 합니다.

In [8]:
arr[5:8] 
Out[8]:
array([12, 12, 12])
In [9]:
arr_slice = arr[5:8] 
In [10]:
arr_slice[1]=12345 
In [11]:
arr 
Out[11]:
array([    0,     1,     2,     3,     4,    12, 12345,    12,     8,            9])
In [12]:
arr_slice 
Out[12]:
array([   12, 12345,    12])

이 경우  arr_slice의 처음 값이 [5], 그리고 2번째 index인 arr_slice[1]값이 전체 arr[6]이기 때문에 12345가 대입이 됩니다. 

1차원 ndarray는 위에서 언급했다시피 list와 비슷하기 때문에 많이 공부 할 필요가 없지만 2차원 이후로부터 좀 공부를 해야하죠. 

 

이제 살펴보도록 합시다.

2. 2/3차원 배열 인덱싱 

 

arr2d = np.array([[1,2,3],[4,5,6],[7,8,9]]) 
In [15]:
arr2d[1] #2차원 배열에서 단순한 색인 값은 스칼라 값이 아니라 1차원 배열이 된다.  
Out[15]:
array([4, 5, 6])

2차원 ndarray를 생성 하였는데, [123],[4,5,6],[7,8,9] 배열을 하나 더 둘러 싸고 있는

그림입니다. 따라서 1번 index는 [4,5,6]전체 배열이 되겠죠?

In [16]:
#개별 스칼라 요소에 접근 할 때는 [][] 처럼 콤마로 구분 된 색인 리스트로 접근 해야 한다 arr2d[1][0] 
Out[16]:
4

반면에 스칼라 값 하나에 접근 하려면 어느 배열의, 어느 열에 속하는지, 지정 해야합니다.

만약에, 2행[2] 0열[0]이면 arr2d[2][0] 즉, 7을 출력하게 되겠습니다.

In [17]:
arr3d = np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]) # 3차원 배열의 경우 잘 시용되지 않지만 층,행,열 로 접근 됨 
In [18]:
arr3d[0] #0층 
Out[18]:
array([[1, 2, 3],        [4, 5, 6]])

해당 배열은 0층과 1층으로 나뉘어져 있는데 맨 앞에 있는 것이 층, 그 다음이 행, 그리고 마지막이 열로서,

index로 접근 할 때도 층,행,열로 접근 하면 됩니다. 다음을 살펴 볼까요?

In [19]:
arr3d[1] #1층 
Out[19]:
array([[ 7,  8,  9],        [10, 11, 12]])

 

1층이기 때문에 위와 같이 출력해 줍니다. 반면에 2층은 존재 하지 않기 때문에 index가 존재하지 않는다고

에러 메세지를 출력하는군요. 바람직 합니다.

In [20]:
arr3d[2] #2층 없음 
 
--------------------------------------------------------------------------- IndexError                                Traceback (most recent call last) <ipython-input-20-f1c4238f3db7> in <module> ----> 1 arr3d[2] #2층 없음  IndexError: index 2 is out of bounds for axis 0 with size 2
In [ ]:
arr3d[0]=42 
In [21]:
old_values = arr3d[0].copy() 
In [22]:
arr3d[0]=42 
In [23]:
arr3d 
Out[23]:
array([[[42, 42, 42],         [42, 42, 42]],         [[ 7,  8,  9],         [10, 11, 12]]])

값을 대입 해 봤습니다. 0층에 42 값을 대입했고,

나중에 다시 값을 바꾸기 위해 old_values에 이전에 있던 값들을 복사 해 놨습니다.

In [24]:
arr3d[0]=old_values 
In [25]:
arr3d 
Out[25]:
array([[[ 1,  2,  3],         [ 4,  5,  6]],         [[ 7,  8,  9],         [10, 11, 12]]])

다시 old_values를 0층에 넣었더니 값이 원래대로 변했습니다.

In [26]:
arr3d[1,0] # -> 1층에, 0행 , 열 생략한 상태 
Out[26]:
array([7, 8, 9])

 

3차원 배열의 index가 어떻게 사용되는 지 알아보기 위해서(층,행,열)직접 코딩을 해 봤습니다.

1층, 0행 이니까, (열은 쓰지 않았음)

[7,8,9],

[10,11,12].

중에서

 

[7,8,9]열을 고를 것 같습니다.

 

예상대로 위에서는 해당 열을 골랐습니다. 그럼 이번에는 열을 골라 봅시다.

In [27]:
arr3d[1,1,1] # -> 1층, 1행, 1열 
Out[27]:
11

1층이므로, 
[7,8,9]
[10,11,12]
1행이므로
[10,11,12]
1열이므로

11을 출력 할 것입니다.

 

헷갈리신다면 다시 한 번 보시면 이해가 가실 겁니다. 별로 어렵지 않은 부분이니까요.

 

 

3. 색인과 슬라이싱 기초 / 슬라이스 색인

 

#--------------------슬라이스 색인----------------------# 
In [29]:
arr2d 
Out[29]:
array([[1, 2, 3],        [4, 5, 6],        [7, 8, 9]])
In [30]:
arr3d 
Out[30]:
array([[[ 1,  2,  3],         [ 4,  5,  6]],         [[ 7,  8,  9],         [10, 11, 12]]])
In [31]:
arr2d[:2] #2행까지 슬라이싱 
Out[31]:
array([[1, 2, 3],        [4, 5, 6]])

2차원 ndarray도 1차원 ndarray를 조금 확장 해서 생각해 보시면 됩니다.

층, 행, 열이라고 했는데, 2darray에는 층이라는 게 존재하지 않으므로 신경 쓸 필요가 없습니다.

행을 슬라이스 , 즉, 2행 이상을 모두 잘라서 보여주는 거라고 생각 하시면 됩니다.

In [32]:
arr2d[:2,1:] #2행까지 슬라이싱 하고, 1열이후로 슬라이싱 
Out[32]:
array([[2, 3],        [5, 6]])

뒤에 열이 붙긴 했지만 2행 위를 자르고, 1행 다음으로 자른 슬라이싱을 출력합니다.

위에 슬라이싱 개념을 생각해 보시고 조금 확장 해서 생각해 보시면 될 것 같습니다.

In [33]:
arr2d[1,:2] #arr2d[1,] 이렇게 사용하는 것을 정수 색인이라고 한다. 나중에 다르게 사용되는 것도 있으니 알아두도록 한다.  
Out[33]:
array([4, 5])

해당 1: 이나 :1 이 아닌 1이라고 쓰는 것을 정수 색인이라고 합니다.

나중에 판다스랑 조금 다르게 사용되는 부분이 있으므로 기억해 두시기 바랍니다.

이 부분은 정확히 1행에, [4,5,6] 2열 아래로 자르므로 [4,5]행을 출력합니다.

In [34]:
arr2d[:,:1] #:만 사용하면 전체 축(모든 행 또는 모든 열)을 의미한다. 따라서 원래 차원의 슬라이스를 얻을 수 있다.  
Out[34]:
array([[1],        [4],        [7]])

마지막으로 전체 행을 뜻하는 : 을 알아 봅시다. : 전체 행에서 , :1 1열 전을 얘기하므로,

[1]

[4]

[7]

열만 출력합니다.

 

 

넘파이에는 슬라이스 색인 이외에도 불리언 색인과 팬시 색인이라는 중요한 개념이 있는데 이 부분은 좀 더 공부를 하고 포스팅을 할 예정입니다. 그 이전까지는 파이썬에 집중 해야죠. 그럼 오늘 포스팅은 여기까지 하고 마치도록 하겠습니다. 
 
 
 
 
 
 

 

 파이썬에서 가장 많이 사용하는 변수 형 중 하나로 리스트가 있습니다. 다른 언어에서 배열로 생각하면 되지만 다른 언어보다 기능이 좀 더 추가되어서 진화된(?) 배열이라고 생각하시면 될 것 같습니다. 그리고 나중에 학습 할 Numpy 배열인 Ndarray는 보다 더 효율적인 함수들을 많이 가지고 있습니다. 그럼 IDE를 키시고 코딩을 시작하시죠.

 

 

1. 리스트의 생성과 인덱싱/슬라이싱

 

 - 리스트의 생성은 위아 같이 a = [ ]  처럼 셍성을 합니다. 만약 [ ] 로 생성을 하면 빈 배열을 생성한다는 뜻인데, 처음에는 초기화 해주는 것이 좋습니다. Null값 때문에 값을 넣을 수 없다는 에러 값을 자주 내뱉기 때문입니다. 부득이한 경우에는 어쩔 수 없지만 말이죠.

 

 - a[0] a[1] a[-1] 처럼 저번에 String에서 배웠던 것처럼 인덱싱을 할 수 있습니다. a 리스트는 0번 인덱스에 1값을 가지고 있기 때문에 a[0]에 따라 1값을 출력합니다. 그리고 저번에 -1은 맨 끝 값을 의미한다고 했습니다. 그렇기 때문에 a[-1]은 a리스트의 마지막 원소인 4를 출력합니다.

 

 - 리스트 슬라이싱의 경우도 스트링과 비슷합니다. 리스트 또한 스트링 처럼 슬라이싱하라고 명령을 할 수 있는데 이 경우에는 a 리스트의 0에서 2를 자르라고 명령 을 하였습니다. 따라서 0인덱스 부터 2인덱스 바로 이전인 1인덱스까지인 [1, 2]를 출력해 줍니다.

 

2. 주요 리스트 함수.

 

 

자주 쓰는 메서드 및 함수들에 대해서 살펴보도록 하겠습니다.

 

2.1 Append / Extend

 

 두 메서드 둘 다 리스트에 원소를 추가하는 메서드입니다. 언뜻 보면 똑같아 보입니다. a에 원소 하나를 append 했더니 1,2,3,4,5가 되었다.

 그 다음에 [1,2,3,4,5] 리스트 안에 리스트를 더 추가하고 싶어서 extend를 써 봤습니다. append는 앞에서 그냥 원소가 추가 되었으니까. 그럼 그냥 append로 추가 해 봤습니다. 그랬더니 list가 들어갔습니다.

 

그러면 extend는 대체 하는 일이 뭘까요? 위에서 보시다시피 리스트를 리스트의 엘레멘트들로 추가 하는 역할을 합니다. append(1)은 에러가 나지 않지만 extend(1)은 에러가 납니다. extend는 에러가 나기 때문입니다. 두 메서드의 차이점을 아시고 사용하시기 바랍니다.

 

2.2 Clear

3.5 버전인가 3.3 이후에 추가된 메서드로, 특정 리스트를 모두 제거하는 함수입니다. 기존에는 del메서드를 사용해서 del a[:] (주 : 는 전체를 슬라이싱 하므로, 리스트의 전체를 의미함) a리스트의 전체를 삭제 하였습니다. 하지만 이제는 clear함수를 사용 할 수 있게 되어서 a,clear() 처럼 사용하면 리스트를 모두 비울 수 있게 되었습니다. 따라서 주기적으로 리스트를 삭제 하거나 메모리에서 비울 필요가 있으면 clear()를 사용 해서 편하게 사용 할 수 있게 되었습니다.  

 

 

 

3. pop

리스트의 가장 기본은 위의 1,2번으로 끝입니다. 노가다 코딩으로 (ㅎㅎ) 할 수 있지만 좀 더 효율적인 코딩을 위해서 상황에 맞게 Numpy를 사용하고 파이썬만을 사용한다면 다른 메서드들을 사용하는 것입니다. 귀찮으신 분들은 위에 1,2,번 까지만 보세요. 아래는 좀 덜 중요한 함수입니다. 하지만 그래도 그렇게 수준급이 아닌 제가 많이 사용하는 함수이니 익혀 두시는 것도 좋을 듯 합니다.

 

pop은 자료구조를 좀 배워 보신 분은 아시겠지만 pop구조라는 것을 아시는 분도 있이실 겁니다. 뒤에서부터 뺴내는 거죠.

 

 

 

위와 같은 방식으로 말입니다. 그래서 기본적으로 a.pop()이렇게 써 놓으면 리스트의 맨 뒤에서부터 한 번 출력한 다음에 빼내지만 괄호안에 인덱스를 써주면 인덱스에 있는 리스트 값을 출력하고 빼냅니다. 그래서 위와 같이 실제 코딩 할 때 print (a.pop()) 처럼 사용 할 수 있습니다.  그러면 리스트의 뒤에서 값이 하나씩 출력되면서 값이 하나씩 빠져 나오는 코드가 생성됩니다.  아직 배우진 않았지만 반복문이랑 같이 사용해보면 다음과 같이 쓰여지겠죠.

 

for i in range(0, 10):

print(a.pop())

 

4. insert/count

 

 append나 extend는 뒤에만 값을 붙여 넣을 수 있었지만 insert의 경우에는 인덱스를 정해서 값을 집어 넣을 수 있습니다. 위에서는 값만 집어 넣지만 a.insert(0,[1,2,3])처럼 리스트를 집어 넣을 수도 있습니다. 하지만 특별한 경우가 아니면 인덱스까지 굳이 찾아서 프로그래밍을 하지 않기 때문에 계속 사용하지는 않죠 ㅎㅎ append나 아니면 미리 리스트의 형태를 만들어서 대입을 해주는 경우가 많습니다. 그래도 알아둬서 나쁠 건 없는 메서드 입니다. 필요 할 경우가 분명히 있긴 있거든요.

 

count는 리스트 내부의 값을 세는 메서드 입니다. 저도 실제로 그렇게 사용해 봤습니다. 하지만 별도로 용도가 있는 지는 모르겠군요.

 

 

 

 

 

 

 

 

 

이제 마지막으로 Dictionary만 하면 대략적인 자료형은 끝이 나는군요 ㅎㅎ 자료형이 끝나면 제어문으로 바로 넘어가면 되겠습니다!

 

'머신러닝 > 기초 문법' 카테고리의 다른 글

5. 딕셔너리 심화 - (2)  (0) 2019.01.30
5. 딕셔너리 기초 - (1)  (0) 2019.01.29
3. String -(2) : string 함수  (0) 2019.01.24
3. String - (1)  (0) 2019.01.22
2. 간단한 숫자 자료형과 해당 형식 지정자  (0) 2019.01.20

 저번에는 숫자형식과 그 포맷팅에 대해서 간단하게 알아 보았습니다. 이번에는 숫자형식 다음으로 String에 대해서 짚어 보도록 하겠습니다. C언어나 다른 언어처럼 달리 실제로 String을 많이 사용하지는 않지만 파이썬은 LIST와 깊은 연관을 가지고 있기 때문에 DEEP하게 살펴보도록 한다고 이전에 숫자형에서 말씀 드렸었습니다. 그럼 이번에도 iPython과 같은 IDE를 키고 실제로 타이핑을 하면서 한 번 알아보도록 하겠습니다.

 

1. Definition and escape code

일단 문자열 자료형을 만드는 방법은 간단합니다.

" "나 ' '안에 선언 하면 되는 거죠. 하지만 's와 같이 string안에 ' 기호를 포함시켜야 할 경우가 있을 지도 모르니까, 가능하면 " "로 선언하는 것이 좋습니다. 따라서 " "로 선언하고, 줄바꿈 기호로 \n을, 그리고 tab으로 칸을 띄우고 싶을 때, \t를 사용합니다. 실제로 코딩을 한 번 해보죠.

 

 

이외에도 스트링에서 사용되는 이스케이프 코드는 인터넷에서 검색하면 바로 나오기 때문에 따로 첨부하지 않았습니다. \n과 \t중 뭔가 자주 쓰이냐 하면 당연히 \n입니다. 줄 개행이 훨씬 코드에서 많이 실 생활에서 사용되는 것을 생각하면 코드에서도 이해하기 쉽죠.

2. 문자열 연산

문자열 연산은 상당히 직관적인데. 더하기, 즉 string1이 korea string2가 fighting 으로 정의되어 있는데 string1 + string2라고 하면 당연히 koreafighting이 됩니다. 그리고 string1*100하면 koreakoreakoreakorea........해서 korea가 100개 정의되게 됩니다. 참고로 /, mod등의 기타 연산은 안 된다는 것도 알아두세요.

 

 

3. 문자열 인덱싱

매우, 매우 매우 중요합니다. string에서도 중요하고, 이 다음에 배울 list와도 관련된 부분이기 때문에 미리 제대로 공부해 두면 좋습니다. 일단 개념부터 알아 두겠습니다.

 

  string = "MyNameIs"

 

위와 같은 String을 정의 해 본다고 합시다. 그렇다면 첫 번째 index는 뭘까요? 백문이 불여 일타라고 일단 쳐봅시다.

 

 

 대문자 M "My"의 M입니다. 이 부분이 프로그램을 처음 하시는 분들이 가장 햇갈려 하는 부분 중 하나인데,  인덱스는 0부터 시작합니다. 1이 아닙니다. 그렇다면 -1은 뭘까요. 음, 눈치 빠르신 분들, 그리고 프로그래밍 좀 하시는 분들은 이미 아시겠지만 문자열의 끝부분을 가리키는 것입니다. 그리고 [-2] [-3] [-4]는 여기 나오진 않았지만 끝에서부터 첫부분까지 거꾸로 indexing하는 것입니다.

 조금 햇갈리실 수도 있지만 몇 번 키보드로 직접 타이핑 하시다 보면 금방 이해 하실 수 있으실 거라고 생각합니다. 저도 그랬으니까요. 문제 없습니다! 

 

4. 문자열 슬라이싱

 이 부분은 파이썬 만의 특징이자 장점인데 저는 C언어를 조금 핥다 시피 하면서 파이썬으로 넘어온터라 정말 놀라웠고 혁신(?)적인 언어라고 생각했습니다. 문자열을 인덱스로 슬라이싱 하다니! 어떻게 프로그래밍 언어에 이런 짓을 할 생각을 했지? 라면서요. 사족은 접고. 본격적으로 들어가면,

 문자열 슬라이싱은 말 그대로 문자열을 자르는 겁니다. 예를 들어서, 앞의 MyNameIs라는 문자열 앞의 [2]인덱스 앞을 자르고 싶다, 하면 그렇게 할 수 있고, [2]부터 [5]까지 자르고 싶다 하면, 그렇게 할 수도 있습니다. 그러면 어떻게 그렇게 할까? 는 코딩 하면서 보면 되겠습니다.

 

 

 

[3]번 index전까지 자르고 출력해 보고 싶다. 하면 [0:2]이렇게 쓰면 되는데, 이건 0 에서 2즉, 3번 전까지를 의미합니다. 반면에 :는 모든 string을 의미 합니다. 따라서 [0:] 이렇게 쓰면 0번째에서 남은 모든 string을 의미하게 되어 모든 string을 출력하게 되겠죠. 또한 슬라이싱은 index에서 쓸 수 있는 것을 모두 쓸 수 있기 때문에 -1, -2, -3도 모두 쓸 수 있습니다. 따라서 [4:-1]은 4번째인 m부터 -1번째 전인 I까지를 출력하게 되겠죠.

 

이제 남은 것은 문자열 함수인데, 해당 부분은 문자열에서만 사용하고 다른 부분에서는 그렇게 중요하게 사용되지 않습니다. 하지만 이 역시 가볍게 파이썬 언어에서 가볍게 다뤄서는 안 될 주제이기 때문에 별도의 테마에서 다루도록 하겠습니다.

 

 

 

 

+ Recent posts