이번 포스팅에서는 Python NumPy 배열(array) 데이터를 외부 파일로 저장(save)하는 방법, 외부 파일을 배열로 불러오는(load) 방법에 대해서 알아보겠습니다.


  • np.save() : 1개의 배열을 NumPy format의 바이너리 파일로 저장하기 (Save a single array to a binary file in NumPy format)
  • np.load() : np.save()로 저장된 *.npy 파일을 배열로 불러오기 (Open a *.npy file and load it as an array)
  • np.savez() : 여러개의 배열을 1개의 압축되지 않은 *.npz 포맷 파일로 저장하기 (Save several arrays into a single file in uncompressed .npz format)
  • np.load() : np.savez()로 저장된 *.npz 파일을 배열로 불러오기 (Open a *.npz file and load it as an array)
  • np.savez_compressed() : 여러개의 배열을 1개의 압축된 *.npz 포맷 파일로 저장하기 (Save several arrays into a single file in compressed .npz format)
  • np.load() : np.save_compressed()로 저장된 압축된 *.npz 파일을 배열러 불러오기 (Open a compressed *.npz file and load it as an array)
  • np.savetext(: 여러개의 배열을 텍스트 파일로 저장하기 (Save several array to a file as plain text)
  • np.loadtext(: 텍스트 파일을 배열로 불러오기 (Open a text file and load it as an array)


[ Python NumPy 배열을 파일로 저장하기(save), 불러오기(load) ]




하나씩 간단한 예를 들어서 설명하겠습니다. 


 > np.save() : 1개의 배열을 NumPy format의 바이너리 파일로 저장하기

 > np.load() : np.save()로 저장된 *.npy 파일을 배열로 불러오기 



In [1]: import numpy as np


In [2]: x = np.array([0, 1, 2, 3, 4])


# 배열을 저장하기

In [3]: np.save('D:/admin/Documents/x_save', x) # x_save.npy


[ .npy 형식으로 저장된 파일 ]


# 배열로 불러오기

In [4]: x_save_load = np.load('D:/admin/Documents/x_save.npy')


In [5]: x_save_load

Out[5]: array([0, 1, 2, 3, 4])

 




 > np.savez() : 여러개의 배열을 1개의 압축되지 않은 *.npz 포맷 파일로 저장하기

 > np.load() : np.savez()로 저장된 *.npz 파일을 배열로 불러오기



In [6]: x = np.array([0, 1, 2, 3, 4])


In [7]: y = np.array([5, 6, 7, 8, 9])


In [8]: np.savez('D:/admin/Documents/xy_savez'

   ...: , x=x, y=y) # 각 배열에 이름 부여

 

 [ .npz 형식으로 저장된 파일 ]



np.load() 함수로 .npz 파일을 열어서 배열로 불러올 수 있습니다. 이때 불러온 파일의 type은 'numpy.lib.npyio.NpzFile' 이며, 개별 배열을 indexing 하려면 [ ]  를 사용합니다. 


# 배열로 불러오기

In [9]: xy_savez_load = np.load('D:/admin/Documents/xy_savez.npz')


In [10]: type(xy_savez_load)

Out[10]: numpy.lib.npyio.NpzFile


In [11]: xy_savez_load['x']

Out[11]: array([0, 1, 2, 3, 4])


In [12]: xy_savez_load['y']

Out[12]: array([5, 6, 7, 8, 9])

 


np.load() 함수로 연 파일을 더이상 사용할 일이 없으면 메모리 효율 관리를 위해 file.close() 로 닫아주어야 합니다. .close() 로 파일을 닫은 상태에서 indexing 을 하려면 'NoneType' object has no attribute 'open' 에러가 납니다. 


In [13]: xy_savez_load.close()


In [14]: xy_savez_load['x'] # AttributeError: 'NoneType' object has no attribute 'open'

Traceback (most recent call last):


File "<ipython-input-14-14d248a305d2>", line 1, in <module>

xy_savez_load['x'] # AttributeError: 'NoneType' object has no attribute 'open'


File "C:\Users\admin\Anaconda3\envs\py_v36\lib\site-packages\numpy\lib\npyio.py", line 226, in __getitem__

bytes = self.zip.open(key)


AttributeError: 'NoneType' object has no attribute 'open'

 




 > np.savez_compressed() : 여러개의 배열을 1개의 압축된 *.npz 포맷 파일로 저장하기

 > np.load() : np.save_compressed()로 저장된 압축된 *.npz 파일을 배열러 불러오기



In [15]: x = np.arange([0, 1, 2, 3, 4])


In [16]: y = np.array([5, 6, 7, 8, 9])


In [17]: np.savez_compressed('D:/admin/Documents/xy_savez_compress'

    ...: , x=x, y=y)

 

 [ .npz 형식으로 압축되어 저장된 파일 ]



np.load() 함수로 불러오기를 하면 'numpy.lib.npyio.NpzFile' type 이며, [ ] 를 사용해서 배열을 indexing 할 수 있습니다. 사용을 끝냈으면 .close() 함수로 닫아줍니다. 


In [18]: xy_savez_compress_load = np.load('D:/admin/Documents/xy_savez_compress.npz')


In [19]: type(xy_savez_compress_load)

Out[19]: numpy.lib.npyio.NpzFile


In [20]: xy_savez_compress_load['x']

Out[20]: array([0, 1, 2, 3, 4])


In [21]: xy_savez_compress_load['y']

Out[21]: array([5, 6, 7, 8, 9])


In [22]: xy_savez_compress_load.close()

 




 > np.savetext() : 여러개의 배열을 텍스트 파일로 저장하기

 > np.loadtext() : 텍스트 파일을 배열로 불러오기


header, footer 로 '#'으로 시작되는 부가설명을 추가할 수 있습니다. 

fmt 로 포맷을 지정할 수 있습니다. 아래 예에서는 소수점 2자리까지만 고정된 자리수로 표현하도록 해보았습니다. 


In [23]: x = np.array([0, 1, 2, 3, 4])


In [24]: y = np.array([5, 6, 7, 8, 9])


In [25]: np.savetxt('D:/admin/Documents/xy_savetxt.txt'

   ...: , (x, y) # x,y equal sized 1D arrays

   ...: , header='--xy save start--'

   ...: , footer='--xy save end--'

   ...: , fmt='%1.2f') # the second digit after the decimal point

 

 [ Text file 로 저장된 배열 ]



np.loadtxt() 함수로 텍스트 파일을 배열로 불러올 수 있으며, ndarray type 으로 바로 불러오게 됩니다. 


In [26]: xy_savetxt_load = np.loadtxt('D:/admin/Documents/xy_savetxt.txt')


In [27]: xy_savetxt_load

Out[27]:

array([[ 0., 1., 2., 3., 4.],

        [ 5., 6., 7., 8., 9.]])

 

In [28]: type(xy_savetxt_load)

Out[28]: numpy.ndarray




2D array 도 텍스트 파일로 저장할 수 있습니다. 

 

In [29]: x2 = np.arange(12).reshape(3, 4)


In [30]: x2

Out[30]:

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

        [ 4, 5, 6, 7],

        [ 8, 9, 10, 11]])


In [31]: np.savetxt('D:/admin/Documents/x2_savetxt.txt'

    ...: , x2

    ...: , fmt='%1.2f')


 [ Text 파일로 저장된 2D 배열 ]



np.loadtxt() 함수로 텍스트 파일을 배열로 불러올 수 있습니다. 원래의 x2 배열과 정확하게 동일하게 잘 불러왔습니다. 


In [32]: x2_savetxt_load = np.loadtxt('D:/admin/Documents/x2_savetxt.txt')


In [33]: x2_savetxt_load

Out[33]:

array([[ 0., 1., 2., 3.],

        [ 4., 5., 6., 7.],

        [ 8., 9., 10., 11.]])

 


많은 도움이 되었기를 바랍니다. 


728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 Python numpy 배열을 정렬(array sorting)하는 방법에 대해서 소개하겠습니다.

 

- (1) 1차원 배열 정렬 : np.sort(x)

- (2) 1차원 배열 거꾸로 정렬 : np.sort(x)[::-1] , x[np.argsort(-x)]

- (3) 2차원 배열 열 축 기준으로 정렬 : np.sort(x, axis=1)

- (4) 2차원 배열 행 축 기준으로 정렬 : np.sort(x, axis=0)

- (5) 2차원 배열 행 축 기준으로 거꾸로 정렬 : np.sort(x, axis=0)[::-1]

 


[ Python Numpy 배열 정렬: np.sort() ]

 



  (1) 1차원 배열 정렬 : np.sort(x)

 

 

In [1]: import numpy as np


In [2]: x = np.array([4, 2, 6, 5, 1, 3, 0])


In [3]: np.sort(x)

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

 

 

 

참고로, np.sort(x) 메소드는 원래의 배열은 그대로 둔채로 정렬이 된 결과를 복사본으로 반환합니다.

반면에 x.sort() 메소드는 원래의 배열 자체를 정렬합니다.

 

np.sort(x) 

=> 원래 배열은 그래로, 정렬 결과 복사본 반환

x.sort()

=> 배열 자체를 정렬

 

In [2]: x = np.array([4, 2, 6, 5, 1, 3, 0])


In [3]: np.sort(x)

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


In [4]: x

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

 

 In [5]: x = np.array([4, 2, 6, 5, 1, 3, 0])

   ...:


In [6]: x.sort()


In [7]: x

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

 

 

 

 (2) 1차원 배열 거꾸로 정렬 : np.sort(x)[::-1] , x[np.argsort(-x)]

 

배열을 거꾸로 정렬하는 방법에는 2가지가 있습니다.

 

(2-1) np.sort(x)[::-1] : 정렬을 한 후 mirror view 생성

 

 

In [8]: x = np.array([4, 2, 6, 5, 1, 3, 0])


In [9]: x_reverse_1 = np.sort(x)[::-1] # mirror view


In [10]: x_reverse_1

Out[10]: array([6, 5, 4, 3, 2, 1, 0])

 

 

 

(2-2) x[np.argsort(-x)] : np.argsort() 로 index를 받아서 indexing 해오기

 

 

In [11]: x = np.array([4, 2, 6, 5, 1, 3, 0])


In [12]: x_reverse_2 = x[np.argsort(-x)] # copy of reversed sorting


In [13]: x_reverse_2

Out[13]: array([6, 5, 4, 3, 2, 1, 0])

 

 



(3) 2차원 배열 열 축 기준으로 정렬 (from left to right) : np.sort(x, axis=1)


'axis = 1' 옵션을 주면 열 축을 기준으로, 좌에서 우로 (from left to right) 정렬을 합니다. 

이게 좀 헷갈릴 수 있는데요, 아래 예제로 확인해 보시기 바랍니다. 



In [14]: x2 = np.array([[2, 1, 6],

    ...:                       [0, 7, 4],

    ...:                       [5, 3, 2]])


In [15]: x2_sort_axis_1 = np.sort(x2, axis=1) # default


In [16]: x2_sort_axis_1

Out[16]:

array([[1, 2, 6],

        [0, 4, 7],

        [2, 3, 5]])

 




 (4) 2차원 배열 행 축 기준으로 정렬 (from top to bottom) : np.sort(x, axis=0)



In [17]: x2 = np.array([[2, 1, 6],

    ...:                       [0, 7, 4],

    ...:                       [5, 3, 2]])


In [18]: x2_sort_axis_0 = np.sort(x2, axis=0)


In [19]: x2_sort_axis_0

Out[19]:

array([[0, 1, 2],

        [2, 3, 4],

        [5, 7, 6]])

 




 (5) 2차원 배열 열 축 기준으로 거꾸로 정렬 (from bottom to top, reversely) 

     : np.sort(x, axis=1)[::-1]



In [20]: x2 = np.array([[2, 1, 6],

    ...:                       [0, 7, 4],

    ...:                       [5, 3, 2]])


In [21]: x2_sort_axis_0_reverse = np.sort(x2, axis=0)[::-1]


In [22]: x2_sort_axis_0_reverse

Out[22]:

array([[5, 7, 6],

        [2, 3, 4],

        [0, 1, 2]])

 


 

참고로 Python

 - (1) DataFrame 정렬 : DataFrame.sort_values()

 - (2) Tuple 정렬 : sorted(tuple, key)

 - (3) List 정렬 : list.sort(), sorted(list)

http://rfriend.tistory.com/281  을 참고하시기 바랍니다.


사전 자료형(Dictionary)의 키, 값 기준 정렬은 https://rfriend.tistory.com/473 를 참고하세요. 


데이터 형태마다 정렬 함수, 메소드가 조금씩 달라서 매번 헷갈리곤 합니다. ㅜ_ㅜ

 

많은 도움 되었기를 바랍니다.

 

728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 Python numpy 의 메소드, 함수 중에서 


- 최소값, 최대값, 혹은 조건에 해당하는 색인(index) 값을 찾기 

   : np.argmin(), np.argmax(), np.where()


- 최소값, 최대값, 혹은 조건에 맞는 값 찾기 

   : np.min(), np.max(), x[np.where()]


에 대해서 소개하겠습니다. 


분석할 때 꽤 많이 사용되므로 기억해두시면 좋겠습니다. 





  (1) 최소값(min), 최대값(max): np.min(), np.max()


x.min(), np.min(x), min(x) 모두 동일한 결과를 반환합니다. 



In [1]: import numpy as np


In [2]: x = np.array([5, 4, 3, 2, 1, 0])


In [3]: x.min()

Out[3]: 0


In [4]: np.min(x)

Out[4]: 0


In [5]: x.max()

Out[5]: 5


In [6]: np.max(x)

Out[6]: 5

 




  (2) 최소값, 최대값의 색인 위치: np.argmin(), np.argmax()



In [7]: x.argmin()

Out[7]: 5


In [8]: np.argmin(x)

Out[8]: 5


In [9]: x.argmax()

Out[9]: 0


In [10]: np.argmax(x)

Out[10]: 0

 




  (3) 조건에 맞는 값의 색인 위치: np.where()


배열에서 3과 같거나 큰 값을 가지는 색인의 위치를 알고 싶을 때, 


 

In [11]: np.where(x >= 3)

Out[11]: (array([0, 1, 2], dtype=int64),)




(4) 조건에 맞는 값을 indexing 하기: x[np.where()] 


배열에서 3과 같거나 큰 값을 indexing 하고 싶을 때, 



In [12]: x[np.where(x >= 3)]

Out[12]: array([5, 4, 3])

 




  (5) 조건에 맞는 값을 특정 다른 값으로 변환하기

     : np.where(조건, 조건에 맞을 때 값, 조건과 다를 때 값)


배열의 값이 3과 같거나 크면 3으로 변환하고, 3보다 작으면 그대로 값을 유지하고 싶을 때, 

(for loop & if else 조건문을 사용하는 것보다 수십배 빠르므로 매우 유용함)



In [13]: np.where(x >= 3, 3, x)

Out[13]: array([3, 3, 3, 2, 1, 0])

 


 

참고로, 위의 np.where를 사용한 배열 값 변환을 for loop & if else 조건문을 사용해서 써보면 아래와 같습니다. for loop은 데이터 사이즈가 커질 경우 속도가 매우 느려지므로, 위의 대용량 데이터는 벡터화된 연산을 하는 np.where() 함수 사용을 권합니다. .

 

 

In [14]: x_2 = []

    ...: for i in list(x):

    ...: if i >= 3:

    ...: x_2.append(3)

    ...: else:

    ...: x_2.append(i)

    ...:

    ...:


In [15]: x_2 = np.asarray(x_2)


In [16]: type(x_2)

Out[16]: numpy.ndarray


In [17]: x_2

Out[17]: array([3, 3, 3, 2, 1, 0])

 

 

많은 도움이 되었기를 바랍니다. 

 

728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 Python numpy 의 집합함수(set functions)에 대해서 알아보겠습니다.

 

한 개, 혹은 두 개의 1차원 ndarray 집합에 대해서

 

(1) unique(x) : 배열 내 중복된 원소 제거 후 유일한 원소를 정렬하여 반환
(2) intersect1d(x, y) : 두 개의 배열 x, y 의 교집합을 정렬하여 반환
(3) union1d(x, y) : 두 개의 배열 x, y의 합집합을 정렬하여 반환
(4) in1d(x, y) : 첫번째 배열 x가 두번째 배열 y의 원소를 포함하고 있는지 여부의 불리언 배열을 반환
(5) setdiff1d(x, y) : 첫번째 배열 x로 부터 두번째 배열 y를 뺀 차집합을 반환
(6) setxor1d(x, y) : 두 배열 x, y의 합집합에서 교집합을 뺀 대칭차집합을 반환

 

해주는 다양한 집합함수가 있습니다.

 

[ Python numpy 집합 함수 (set functions) ]

 

 

 

순서대로 예를 들어서 설명하겠습니다.  위의 벤다이어그램을 참고하시기 바랍니다.

 

 (1) np.unique(x) : 배열 내 중복된 원소 제거 후 유일한 원소를 정렬하여 반환

 

 

In [1]: import numpy as np


In [2]: x = np.array([1, 2, 3, 1, 2, 4])


In [3]: np.unique(x)

Out[3]: array([1, 2, 3, 4])

 

 

참고로, pure python의 sorted(set(x)) 와 np.unique(x) 는 동일합니다.

 

In [4]: sorted(set(x))

Out[4]: [1, 2, 3, 4]

 

 

 

 

 

 (2) np.intersect1d(x, y) : 두 개의 배열 x, y 의 교집합을 정렬하여 반환

 

 

In [5]: x = np.array([1, 2, 3, 4])


In [6]: y = np.array([3, 4, 6, 5])


In [7]: np.intersect1d(x, y)

Out[7]: array([3, 4])

 

 

 

 

 (3) np.union1d(x, y) : 두 개의 배열 x, y의 합집합을 정렬하여 반환

 

 

In [8]: x = np.array([1, 2, 3, 4])


In [9]: y = np.array([3, 4, 6, 5])


In [10]: np.union1d(x, y)

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

 

 

 

 

 (4) np.in1d(x, y) : 첫번째 배열이 두번째 배열의 원소를 포함하고 있는지 여부의

                         불리언 배열을 반환

 

 

In [11]: x = np.array([1, 2, 3, 4, 5, 6])


In [12]: y = np.array([2, 4])


In [13]: np.in1d(x, y)

Out[13]: array([False, True, False, True, False, False])

 

 

 

 

 (5) np.setdiff1d(x, y) : 첫번째 배열 x로 부터 두번째 배열 y를 뺀 차집합을 반환

 

 

In [14]: x = np.array([1, 2, 3, 4])


In [15]: y = np.array([3, 4, 5, 6])


In [16]: np.setdiff1d(x, y)

Out[16]: array([1, 2])

 

 

 

 

 (6) np.setxor1d(x, y) : 두 배열 x, y의 합집합에서 교집합을 뺀 대칭차집합을 반환

 

 

In [17]: x = np.array([1, 2, 3, 4])


In [18]: y = np.array([3, 4, 5, 6])


In [19]: np.setxor1d(x, y)

Out[19]: array([1, 2, 5, 6])

 

 

많은 도움이 되었기를 바랍니다.

728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 Python의 numpy 라이브러리에 있는 함수들을 이용해서 두 개의 배열(array)을 옆으로 붙이기, 배열을 위 아래로 붙이기(concatenate) 하는 방법에 대해서 소개하겠습니다.  알아두면 편리하게 배열을 조작할 수 있는 유용한 함수들입니다. 


(1) 두 배열을 왼쪽에서 오른쪽으로 붙이기 

   : np.r_[a, b]

   : np.hstack([a, b])
   : np.concatenate((a, b), axis = 0)


(2) 두 배열을 위에서 아래로 붙이기

   : np.r_[[a], [b]]

   : np.vstack([a, b])

   : np.concatenate((c, d), axis = 1) # for 2D ~ array


(3) 두 개의 1차원 배열을 칼럼으로 세로로 붙여서 2차원 배열 만들기

    (Stack 1-D arrays as columns into a 2-D array)

   : np.c_[a, b]

   : np.column_stack([a, b])

   : np.concatenate((c.T, d.T), axis = 1) # for 2D~ array


 [ 배열을 옆으로, 위 아래로 붙이기 : np.r_, np.c_, np.hstack(), np.vstack(), np.column_stack(), np.concatenate(axis=0), np.concatenate(axis=1) ]




처음에 np.r_[a, b], np.c_[a, b] 코드를 봤을 때 '이게 뭐지?', '잘못 타이핑한거 아닌가?', '쓰다 말았나?' 하고 갸우뚱 했던 기억이 납니다. ^^; 


아래에 간단한 예를 들어서 설명하겠습니다. 

np.r_[], np.c_[] 는 코드가 완전 간단한 장점이 있구요, np.hstack(), np.vstack(), np.column_stack() 는 코드 이해가 쉬운 장점이 있는데요, 코드 작성하시는 분의 선호도에 따라 골라 쓰시면 되겠습니다. 


먼저 numpy 라이브러리 importing 한 후에 a, b 두 개의 예제 배열(array)을 만들겠습니다. 



In [1]: import numpy as np


In [2]: a = np.array([1, 2, 3])


In [3]: b = np.array([4, 5, 6])


 



(1) 두 배열을 왼쪽에서 오른쪽으로 붙이기 

   : np.r_[a, b]     <- ( ) 를 사용하지 않고 [ ] 를 사용하는 것에 주의하세요

   : np.hstack([a, b])
   : np.concatenate((a, b), axis=0)


 

 In [4]: np.r_[a, b]

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


 In [7]: np.hstack([a, b])

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


 In [23]: np.concatenate((a, b), axis = 0)

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




(2) 두 배열을 위에서 아래로 붙이기

   : np.r_[[a], [b]]   <- a, b 배열을 [ ]을 사용해서 1-D 배열로 만든거 주의하세요

   : np.vstack([a, b])
   : np.concatenate((c, d), axis = 1<- 1D 배열은 "
AxisError: axis 1 is out of bounds for array of dimension 1"라는 AxisError가 나네요. 2D 이상 배열은 에러 없이 잘 되구요. 



In [5]: np.r_[[a], [b]]

Out[5]:

array([[1, 2, 3],

        [4, 5, 6]])

 


In [8]: np.vstack([a, b])

Out[8]:

array([[1, 2, 3],

        [4, 5, 6]])

 


 In [27]: c = np.array([[0, 1, 2], [3, 4, 5,]])

    ...: d = np.array([[6, 7, 8], [9, 10, 11]])


In [28]: np.concatenate((c, d), axis = 1) # for 2D~ array

Out[28]:

array([[ 0,  1,  2,  6,  7,  8],

        [ 3,  4,  5,  9, 10, 11]])




(3) 두 개의 1차원 배열을 칼럼으로 세로로 붙여서 2차원 배열 만들기

    (Stack 1-D arrays as columns into a 2-D array)

   : np.c_[a, b]

   : np.column_stack([a, b])

   : np.concatenate((c.T, d.T), axis = 1) # for 2D~ array



In [6]: np.c_[a, b]

Out[6]:

array([[1, 4],

        [2, 5],

        [3, 6]])

 


In [9]: np.column_stack([a, b])

Out[9]:

array([[1, 4],

        [2, 5],

        [3, 6]])




np.concatenate(axis=1) 은 1D array 로 하면 AxisError 가 납니다. 2D array 이상에 대해서 사용하세요. 


 In [27]: c = np.array([[0, 1, 2], [3, 4, 5,]])

    ...: d = np.array([[6, 7, 8], [9, 10, 11]])


In [29]: np.concatenate((c.T, d.T), axis = 1)

Out[29]:

array([[ 0,  3,  6,  9],

       [ 1,  4,  7, 10],

       [ 2,  5,  8, 11]])




많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되셨다면 아래의 '공감~'를 꾸욱 눌러주세요. ^^



728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 Python의 for loop 반복문에서 사용할 수 있는 일정 간격, 혹은 일정 개수의 수를 생성하는 함수를 소개하겠습니다.

 

(1) range() 함수

   : start, stop, step 을 인수로 받아 일정 간격의 정수 생성

 

(2) enumerate() 함수

   : 순서가 있는 자료형(리스트, 튜플, 문자열)을 인수로 받아 인덱스(index)를 포함하는 객체를 반환

 

(3) np.linspace() 함수

   : start, stop, num 을 인수로 받아 일정 개수/간격의 샘플을 반환

 

(4) linrange() 사용자정의 함수

  : start, stop, step 을 인수로 받아 일정 간격의 샘플을 반환

 

 

[ Python의 for loop 문에 사용할 수 있는 함수들 예시 ]

 

 

 

 (1) range() : start, stop, step 을 인수로 받아 일정 간격의 정수 생성

 

for loop 문을 작성할 때 일반적으로 같이 사용하는 함수가 range() 함수 입니다. 3개의 parameter 값을 입력받게 되는데요, range(start, stop, step) 의  

 - start : 순열의 처음 시작하는 수

 - end : 순열의 끝나는 수, 단 이 숫자는 포함하지 않음

 - step : 순열 안의 각 숫자들 간의 간격

을 의미합니다.

  • 1개의 parameter 만을 입력하는 경우 그 수는 end 의 값으로 인식되며(해당 값은 미포함), start=0, step=1 의 디폴트 값이 자동으로 설정됩니다.  

# One parameter

In [1]: for i in range(10):

   ...: print(i)

   ...:

   ...:

0

1

2

3

4

5

6

7

8

9

 

 

  • 2개의 parameter를 입력하는 경우, 각 값은 start와 end 로 인식되고, step=1 로 자동 설정됩니다.

# Two parameters

In [2]: for i in range(5, 10):

   ...: print(i)

   ...:

   ...:

5

6

7

8

9

 

 

  • 3개의 parameter를 입력하는 경우, 각 값은 start, end, step의 값이 됩니다. end에 입력한 값은 포함되지 않는 다는 점에 주의하세요.

# Three parameters

In [3]: for i in range(0, 10, 2):

   ...: print(i)

   ...:

   ...:

0

2

4

6

8

 

 

  • step 위치에 음수(-) 값을 입력하면 그 수만큼 줄어드는 방향으로 순열을 생성합니다.

# Going backwards

In [4]: for i in range(5, -5, -2):

   ...: print(i)

   ...:

   ...:

5

3

1

-1

-3

 

 

  • List 에 대해서도 len() 함수로 리스트 안의 원소 개수를 파악하고 range() 함수를 적용하여 for loop으로 List 안의 원소를 indexing 해오는 반복문을 만들 수 있습니다.

 

In [5]: my_list = ['a', 'b', 'c', 'd', 'e']

   ...: for i in range(0, len(my_list)):

   ...: print(my_list[i])

   ...:

   ...:

a

b

c

d

e

 

 

 

 

 (2) enumerate() : 순서가 있는 자료형(리스트, 튜플, 문자열)을 인수로 받아
                         인덱스(index)를 포함하는 객체를 반환

 

enumerate() 함수는 아래의 예제처럼 객체의 index 를 파악하고자 할 때 사용하면 매우 유용합니다.

 

 

In [6]: name_list = ['Lee', 'Kim', 'Park', 'Choi']

   ...: for i, name in enumerate(name_list):

   ...: print(i+1, name)

   ...:

   ...:

(1, 'Lee')

(2, 'Kim')

(3, 'Park')

(4, 'Choi')

 

 

 

아래의 예제처럼 enumerate()와 format() 함수를 적절히 같이 사용하면 꽤 쓸만합니다.

 

 

In [7]: for i, name in enumerate(name_list):

   ...: print("idx: {} , name: {} ".format(i+1, name))

   ...:

   ...:

idx: 1 , name: Lee

idx: 2 , name: Kim

idx: 3 , name: Park

idx: 4 , name: Choi

 

 

 

 

 (3) np.linspace() : start, stop, num 을 인수로 받아 일정 개수/간격의 샘플을 반환

 

numpy 패키지의 linspace() 함수는 그래프의 x 축 설정할 때나 혹은 for loop을 써서 시뮬레이션 할 때 꽤 자주 사용하는 편입니다. start, stop, num 의 세 개의 parameter를 입력받아 num 개수, 일정 간격의 샘플을 반환합니다.

 

 - start : 순열의 시작 값

 - stop : 순열의 끝 값, endpoint=True가 기본 설정, 만약 endpoint=False인 경우 미포함

 - num : 생성되는 샘플의 개수

 

  • endpoint=True 가 기본값으로 설정 (stop 값을 포함하여 num 개수만큼의 등간격 순열 생성)

# endpoint=True (default setting)

In [8]: import numpy as np

   ...: np.linspace(start=0, stop=10, num=5)

   ...:

Out[8]: array([ 0. , 2.5, 5. , 7.5, 10. ])

 

 

 

  • retstep=True 를 설정하면 각 샘플 간의 간격을 배열 다음에 표시해줍니다.

# retstep: If True, return (samples, step), where step is the spacing between samples.

In [9]: np.linspace(start=0, stop=10, num=5, retstep=True)

   ...:

Out[9]: (array([ 0. , 2.5, 5. , 7.5, 10. ]), 2.5)

 

 

  • endpoint=False 를 설정하면 stop 매개변수값을 포함하지 않은 등간격의 num 개수 샘플을 생성합니다.
# endpoint: If True, stop is the last sample. Otherwise, it is not included. Default is True.

In [10]: np.linspace(start=0, stop=10, num=5, retstep=True, endpoint=False)

    ...:

Out[10]: (array([0., 2., 4., 6., 8.]), 2.0)

 

 

 

  • for loop 반복문에 np.linspace() 사용한 예제

 

In [11]: for i in np.linspace(start=0, stop=10, num=5):

    ...: print(i)

    ...:

    ...:

0.0

2.5

5.0

7.5

10.0

 

 

 

 

 (4) linrange() 사용자정의 함수 : start, stop, step을 인수로 받아 일정 간격의 샘플 반환

 

위의 (3)번에서 소개한 np.linspace() 함수를 응용하여 일정 간격(step) 의 샘플을 생성해주는 linrange() 사용자정의 함수를 소객합니다. (1)번의 range() 함수와 매우 유사하긴 한데요, stop 값이 포함되어서 step 만큼의 간격으로 순열을 생성해주는게 조금 다릅니다.

 

 

In [12]: def linrange(start=0, stop=1, step=1):

    ...: n = np.round((stop - start) / step)

    ...: array = np.linspace(start, stop, int(n+1)) # endpoint=True

    ...: return array

    

In [13]: for i in linrange(start=0, stop=10, step=2):

    ...: print(i)

    ...:

    ...:

0.0

2.0

4.0

6.0

8.0

10.0

 

 

 

많은 도움이 되었기를 바랍니다.

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾸욱 눌러주세요. ^^

 

 

728x90
반응형
Posted by Rfriend
,

이번 포스팅에서는 파이썬에서 다차원 배열(array)을 1차원 배열로 평평하게 펴주는 NumPy의 ravel() 함수, flatten() 함수에 대해서 알아보겠습니다. 


1차원 배열을 다차원 배열로 재구성/재배열 해주는 NumPy의 reshape() 함수와 반대의 기능을 하는 함수가 ravel(), flatten() 함수라고 보시면 되겠습니다. 


기계학습 알고리즘 학습하다보면 가끔씩 ravel() 함수가 나오는데요, 이참에 order 옵션 'C', 'F', 'K' 별 기능에 대해서도 정리해서 알아두면 좋을 듯 합니다. 


[ Python NumPy ravel() 함수 vs. reshape() 함수 ]




-- 2차원 배열 -- 


먼저 0 ~ 11 까지의 12개의 원소로 이루어진 3 x 4 배열을 만들어 보겠습니다.  



In [1]: import numpy as np

   ...: x = np.arange(12).reshape(3, 4)

   ...: x

   ...:

Out[1]:

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

        [ 4, 5, 6, 7],

        [ 8, 9, 10, 11]])




위에서 만든 2차원 배열에 대해서 order='C', order='F', order='k'별로 순서대로 위의 배열 3*4 배열 x가 어떤 순서대로 평평하게 펴지는지 예제로 살펴보겠습니다. 


(1) np.ravel(x, order='C') : C와 같은 순서로 인덱싱하여 평평하게 배열 (디폴트)



In [2]: np.ravel(x, order='C') # by default

   ...:

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

 




(2) np.ravel(x, order='F') : Fortran과 같은 순서로 인덱싱하여 평평하게 배열



In [3]: np.ravel(x, order='F')

   ...:

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

 




 (3) np.ravel(x, order='K') : 메모리에서 발생하는 순서대로 인덱싱하여 평평하게 배열



In [4]: np.ravel(x, order='K')

   ...:

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





-- 3차원 배열 -- 


3차원 이상의 배열에 대해서도 ravel() 함수를 사용해서 1차원 배열로 평평하게 펼 수가 있습니다. 이때 order 매개변수를 설정해줄 때 조금 주의가 필요합니다. 아래에 2*3*2 의 3차원 배열에 대해서 축이 어떻게 설정되어있느냐(배열 순서가 어떤가)에 따라서 order='C'와 order='K'를 선택해서 사용하면 되겠습니다. 


(4) np.raver(y, order='C') : 3차원 배열의 평평하게 펴기



In [5]: y = np.arange(12).reshape(2, 3, 2)

   ...: y

Out[5]:

array([[[ 0, 1],

         [ 2, 3],

         [ 4, 5]],


        [[ 6, 7],

         [ 8, 9],

         [10, 11]]])

 



In [6]: np.ravel(y, order='C')

   ...:

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

 




 (5) np.ravel(z, order='K') : 축이 바뀐 3차원 배열을 평평하게 펴기



In [7]: z = np.arange(12).reshape(2, 3, 2).swapaxes(1, 2)


In [8]: z

Out[8]:

array([[[ 0, 2, 4],

         [ 1, 3, 5]],


        [[ 6, 8, 10],

         [ 7, 9, 11]]])

 



In [9]: np.ravel(z, order='K')

   ...:

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

 



이상으로 다차원 배열을 1차원 배열로 평평하게 펴주는 numpy.ravel(a, order='C', 'F', 'K') 함수에 대해서 알아보았습니다. 


많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾸욱 눌러주세요. ^^



728x90
반응형
Posted by Rfriend
,

외국의 블로그에 소프트엔지니어 채용 과정 중에 코딩 인터뷰에서 있을 법한 문제로 회자되는 "FizzBuzz" 문제가 있습니다. 


"FizzBuzz"문제는 


 - 1에서 100까지의 숫자를 출력하되, 

 - 만약 해당 숫자가 '3'으로 나누어지면 숫자 대신에 "Fizz"를 출력하고, 

 - 만약 해당 숫자가 '5'로 나누어지면 숫자 대신에 "Buzz"를 출력하며, 

 - 만약 해당 숫자가 '3'과 '5'로 모두 나누어지면 숫자 대신에 "FizzBuzz"를 출력


하는 코드는 짜라는 것입니다.  


1~100까지 하기에는 좀 길기 때문에 1~30까지의 숫자에 대해서만 FizzBuzz 문제를 풀어보면 아래의 Original -> FizzBuzz 변환 전/후 비교를 보시면 이해가 쉬울 것입니다. 




위의 FizzBuzz 문제를 푸는 방법이 여러가지가 있을 수 있을 텐데요, (1) if, elif, else 조건문 사용, (2) if, elif, else 조건문을 포함한 사용자 정의 함수, (3) 문자열 합치기 (concatenating strings) 의 세 가지 방법을 소개합니다. 



  (1) if, elif, else 조건문을 사용한 FizzBuzz 코딩



# (1) if, elif, and else

for num in range(1, 31):

    if num % 3 == 0 and num % 5 == 0:

        print('FizzBuzz')

    elif num % 3 == 0:

        print('Fizz')

    elif num % 5 == 0:

        print('Buzz')

    else:

        print(num)

 




  (2) if, elif, else 조건문과 사용자 정의 함수(UDF)을 사용한 FizzBuzz 코딩


사용자 정의 함수에 대해서는 조만간 포스팅 하겠습니다. ^^



# (2) User Defined Function

def fizzbuzz(num):

    if num % 3 == 0 and num % 5 == 0:

        return 'FizzBuzz'

    elif num % 3 == 0:

        return 'Fizz'

    elif num % 5 == 0:

        return 'Buzz'

    else:

        return str(num)

    

print("\n".join(fizzbuzz(num) for num in range(1, 31)))

 




  (3) 문자열 합치기(Concatenating Strings)을 이용한 FizzBuzz 코딩



# (3) Concatenating Strings

for num in range(1, 31):

    string = ""

    if num % 3 == 0:

        string = string + "Fizz"

    if num % 5 == 0:

        string = string + "Buzz"

    if num % 5 != 0 and num % 3 != 0:

        string = string + str(num)

    print(string)

 



아래 링크는 취업 인터뷰에서 FizzBuzz 코딩 문제를 듣고서 Tensorflow로 딥러닝 모형을 적용했다가 취업 실패했다는 (가상의?) 블로그 내용입니다.  


Fizz Buzz in Tensorflow (http://joelgrus.com/2016/05/23/fizz-buzz-in-tensorflow/)


간단한 '주먹지르기'로 해결할 수 있는 문제를 단지 '최신 유행'하는 기술이라는 이유만으로  '공중 3회전 날아 뒤돌아 발 차고 손목날로 목 가로지르기' 기술을 적용할 필요가 있는가에 대해서 우스개 (가상?) 사례로 소개한 포스팅인 듯 합니다.  Interviewer 의 반응을 유심히 보면서... 인터뷰 과정을 한번 보시는 것도 재미있을 것 같습니다. ㅋㅋ


많은 도움이 되었기를 바랍니다. 

이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾸욱 눌러주세요. 



728x90
반응형
Posted by Rfriend
,

파이썬 NumPy 에서 배열의 차원(Dimension)을 재구조화, 변경하고자 할 때 reshape() 메소드를 사용합니다.  가령, 3개의 행과 4개의 열로 구성된 2차원의 배열로 재설정하고 싶으면 reshape(3, 4) 처럼 reshape()의 매개변수로 변경하고자 하는 배열의 행과 열의 차원을 정수로 입력해주면 됩니다. 


그런데 reshape(-1, 2) 혹은 reshape(3, -1) 처럼 reshape() 메소드 안에 '-1'이 들어가 있는 경우가 있습니다. 이때 reshape()의 '-1'이 의미하는 바는, 변경된 배열의 '-1' 위치의 차원은 "원래 배열의 길이와 남은 차원으로 부터 추정"이 된다는 뜻입니다. (One shape dimension can be -1. In this case, the value is inferred from the length of the array and remaining dimensions.)


말이 좀 어렵고, 금방 이해하기가 쉽지 않은데요, ^^; 아래에 간단한 예를 들어서 설명해보겠습니다. 


먼저 NumPy 라이브러리를 import 하고 3x4 차원의 예제 배열을 만들어보겠습니다. 

(우리가 일상적으로 사용하는 reshape() 의 사용 예제)



In [1]: import numpy as np


In [2]: x = np.arange(12).reshape(3, 4)


In [3]: x.shape

Out[3]: (3, 4)


In [4]: x

Out[4]:

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

        [ 4, 5, 6, 7],

        [ 8, 9, 10, 11]])

 



  (1) reshape(-1, 정수) 의 행(row) 위치에 '-1'이 들어있을 경우


이제 reshape() 의 행(row) 차원 위치에 '-1'을 넣으면 어떻게 재구조화가 되는지 살펴보겠습니다. 

총 12개의 원소가 들어있는 배열 x에 대해서 x.reshape(-1, 정수) 를 해주면 '열(column)' 차원의 '정수'에 따라서 12개의 원소가 빠짐없이 배치될 수 있도록 '-1'이 들어가 있는 '행(row)' 의 개수가 가변적으로 정해짐을 알 수 있습니다.  


x.reshape(-1, 1)

=> shape(12,1)

x.reshape(-1, 2

=> shape(6, 2)

 x.reshape(-1, 3)

=> shape(4, 3)

x.reshape(-1, 4

=> shape(34)

 

In [5]: x.reshape(-1, 1)

Out[5]:

array([[ 0],

        [ 1],

        [ 2],

        [ 3],

        [ 4],

        [ 5],

        [ 6],

        [ 7],

        [ 8],

        [ 9],

        [10],

        [11]])


 In [6]: x.reshape(-1, 2)

Out[6]:

array([[ 0, 1],

        [ 2, 3],

        [ 4, 5],

        [ 6, 7],

        [ 8, 9],

        [10, 11]])







 In [7]: x.reshape(-1, 3)

Out[7]:

array([[ 0, 1, 2],

        [ 3, 4, 5],

        [ 6, 7, 8],

        [ 9, 10, 11]])









 In [8]: x.reshape(-1, 4)

Out[8]:

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

        [ 4, 5, 6, 7],

        [ 8, 9, 10, 11]])













  (2) reshape(정수, -1) 의 열(column) 위치에 '-1'이 들어있을 경우


다음으로 reshape()의 열(column) 위치에 '-1'을 넣으면 어떻게 재구조화되는지 살펴보겠습니다. 

x의 총 원소 12개가 모두 배열될 수 있도록 행(row)의 정수가 정해지면, 이에 따라서 '-1'이 들어있는 열(column)의 개수가 정해짐을 알 수 있습니다. 


즉, 행이나 열의 특정 차원을 기준으로 재배열하고 싶은 행이나 열의 개수가 있으면 나머지 차원의 개수는 '-1'로 해두면 알아서 자동으로 재배열을 해주니 편리한 기능이라고 하겠습니다. 


x.reshape(1, -1)

  => shape(1, 12)

 

In [9]: x.reshape(1, -1)

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


 x.reshape(2, -1)

  => shape(2, 6)

 

In [10]: x.reshape(2, -1)

Out[10]:

array([[ 0, 1, 2, 3, 4, 5],

        [ 6, 7, 8, 9, 10, 11]])


 x.reshape(3, -1)

  => shape(3, 4)

 

In [11]: x.reshape(3, -1)

Out[11]:

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

        [ 4, 5, 6, 7],

        [ 8, 9, 10, 11]])


 x.reshape(4, -1)

  => shape(4, 3)


In [12]: x.reshape(4, -1)

Out[12]:

array([[ 0, 1, 2],

        [ 3, 4, 5],

        [ 6, 7, 8],

        [ 9, 10, 11]])





  (3) reshape(-1) 인 경우


x.reshape(-1)은 x.reshape(1, -1)과 같이 1차원 배열을 반환합니다. 


x.reshape(-1)

 

In [13]: x.reshape(-1)

Out[13]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])


 x.reshape(1, -1)

 

x.reshape(1, -1)

Out[14]: array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11]])





  (4) ValueError: cannot reshape array of size 12 into shape (5)


reshape(-1, 정수) 또는 reshape(정수, -1) 메소드가 제대로 작동하기 위해서는 한가지 조건이 있는데요, 원래의 배열에 있는 원소가 재구조화 혹은 재배열 되려는 배열의 차원에 빠짐없이 분배가 될 수 있어야 한다는 점입니다.  


가령, 위의 (1), (2), (3)번 예에서는 12개의 원소로 구성된 x배열을 (1, 12), (2, 6), (3, 4), (4, 3) 으로 재배열했었습니다. 하지만 아래의 ValueError 가 난 것처럼 12개의 원소로 구성된 원래의 배열 x에 대해 x.reshape(-1, 5) 혹은 x.reshape(7, -1) 로 재구조화하려고 하면 서로 호환이 안되기 때문에 ValueError가 난 것입니다. 



In [15]: x.reshape(-1, 5)

Traceback (most recent call last):


File "<ipython-input-15-3341ca33497d>", line 1, in <module>

x.reshape(-1, 5)


ValueError: cannot reshape array of size 12 into shape (5)

In [16]: x.reshape(7, -1)

Traceback (most recent call last):


File "<ipython-input-16-c8e97ae7c9bc>", line 1, in <module>

x.reshape(7, -1)


ValueError: cannot reshape array of size 12 into shape (7,newaxis)

 




  (5) ValueError: can only specify one unknown dimension


reshape(-1, -1)은 행, 열 어느 차원도 정해주지 않았으므로 ValueError 가 발생합니다. 



In [17]: x.reshape(-1, -1)

Traceback (most recent call last):


File "<ipython-input-17-8142d87a8f95>", line 1, in <module>

x.reshape(-1, -1)


ValueError: can only specify one unknown dimension

 



많은 도움이 되었기를 바랍니다. 


이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾹 눌러주세요. ^^



728x90
반응형
Posted by Rfriend
,

지난번 포스팅에서는 파이썬 프로그램 흐름 제어의 2가지 큰 뼈대 중에서 


(1) 조건이 참(True), 거짓(False)인지에 따라 프로그램 흐름을 나누어 주는 분기문 (Branch statements) 로서 


 - if statements

 - if, else statements

 - if, elif, else statements

 - nested if statements


에 대해서 알아보았습니다. 



이번 포스팅에서는 파이썬 프로그램 흐름 제어의 두번째 주제로서 


(2) 조건이 참이거나 순서열의 끝까지 반복, 중단하게 해주는 반복문(Loop statements) 으로서 


 - while: 조건이 참인 동안 반복 (loop while the condition is True)

 - for: 순서열의 처음부터 끝까지 반복 (loop until the end of the sequence)

 - continue: 조건이 참이면 반복문 계속 (continue loop if the condition is True)

 - break: 조건이 참이면 반복문 중단 (stop loop if the condition is True)


에 대해서 알아보겠습니다. 


반복문(Loop statement)을 잘 사용하면 단순 반복 작업을 컴퓨터에게 시킬 수 있으므로 분석가, 프로그래머에게 소중한 시간을 절약할 수 있게 해주어 매우 유용합니다. 



[ 파이썬 프로그램 흐름 제어 : 반복문 (Loop statement) ]





먼저 while 반복문부터 살펴보겠습니다. 


 (1) while: 조건이 참인 동안 반복 (loop while the condition is True)


while 문은 조건(condition)이 참(True) 인 동안 계속 반복하게 해줍니다. 


for 문은 순서열(sequence)의 항목(item)을 처음부터 끝까지 반복하는데 반해, while 문은 조건(condition)이 참(True)인 동안 반복한다는 차이점이 있습니다. 따라서, for 문처럼 처음과 끝을 알 수 없고, 그저 조건(condition) 을 만족하는 동안에는 반복을 시키고 싶으면 while 반복문을 사용하면 되겠습니다. 


[Syntax of while loop in python]

while condition:

    conditional code block 


while 반복문은 위의 Syntax 처럼 while 다음에 조건(condition)을 써주고 끝에 콜론(colon, :)을 꼭 붙여주어야 합니다. 그 다음줄부터는 조건이 참(condition is True)인 경우에 반복 실행시키고자 하는 code block을 써주는데요, 이때 들여쓰기(indentation)을 해주어야 합니다.(spyder 같은 IDE를 사용하면 알아서 들여쓰기 해주어서 편함)




(1-1) while 반복문


처음에 '0'부터 시작해서 '1'씩 더해가는 과정을 반복하면서, 그 결과값이 '5 미만'인 조건을 만족하는 한(while) 계속해서 그 값을 출력하고 '1'씩 더해가는 반복작업을 하는 아주 간단한 예제를 들어보겠습니다. 


while 반복문

실행 결과 (result)

count = 0

while count < 5:

    print('count : ', count)

    count = count + 1

    

print('The end')

count : 0

count : 1

count : 2

count : 3

count : 4

The end




(1-2) else 조건문과 함께 사용하는 while 반복문


while 반복문에 else 조건문을 같이 사용할 수 도 있습니다. 

아래에 '0' 부터 시작해서 '1'씩 더해가는 과정을 반복하면서, 그 결과 값이 '5 미만'인 조건을 만족하는 한(while) 계속해서 '5보다 작다'를 출력하고 이전 값에 '1'씩 더해가며, '5 미만' 조건을 만족하지 않으면(else) '5보다 작지 않다'를 출력하고 반복을 멈추는 예제를 들어보겠습니다. 


while 반복문 

실행 결과 (result) 

count = 0

while count < 5:

    print(count, ' is less than 5')

    count = count + 1

else:

    print(count, ' is not less 5 so stop here') 

0  is less than 5

1  is less than 5

2  is less than 5

3  is less than 5

4  is less than 5

5  is not less 5 so stop here




(1-3) 무한 반복문 (infinite loop)


while 반복문의 조건을 True 로 해놓으면 컴퓨터의 전원을 끄지 않는 한 계속해서, 무한 반복(infinite loop)하게 됩니다. 무한 반복을 어디에 써먹을 수 있을까 싶을 텐데요, 서버처럼 연중 무중단 운영을 하는 경우 유용하게 사용할 수 있습니다. (while(True): 또는 while True: )


아래 예제에서는 무한반복해서 프린트하는 것을 spyder의 우측 상단의 중단 단추를 눌러서 강제로 종료시켰습니다. (KeyboardInterrupt)


while 반복문 (infinite loop)

실행 결과 (result) 

 # Infinite loop

while(True):

    print('Infinite loop goes on and on ...')

Infinite loop goes on and on ...

Infinite loop goes on and on ...

Infinite loop goes on and on ...


File "zmq/backend/cython/checkrc.pxd", line 12, in zmq.backend.cython.checkrc._check_rc (zmq\backend\cython\socket.c:9621)


KeyboardInterrupt



while 무한 반복문(while True: )에 지난번 포스팅에서 살펴보았던 if, elif, else 분기문과 break 반복문 제어문을 같이 사용할 수도 있겠지요?  아래는 사용자로부터 input()으로 answer 를 받아서, answer 별로 다른 메시지를 출력하는 과정을 무한 반복(while True:  이므로...)하되, elif 조건에 해당하면 무한반복을 중단(break) 하도록 하는 예제입니다. 말로 설명하려니 너무 주저리주저리 인데요, 아래 코드와 실행 결과를 살펴보시면 이해가 금방 갈 겁니다. 


 while 반복문 (with if, elif, else & break)

실행 결과 (result) 

while True:

    print('continue or stop? [continue/stop]:')

    answer = input()

    

    if answer == 'continue':

        print('>> continue again!')

    elif answer == 'stop':

        print('>> stop here!')

        break

    else:

        print('>> wrong answer!')

continue or stop? [continue/stop]:


continue

>> continue again!

continue or stop? [continue/stop]:


repeate

>> wrong answer!

continue or stop? [continue/stop]:


continue

>> continue again!

continue or stop? [continue/stop]:


stop

>> stop here!




 (2) for:  순서열의 처음부터 끝까지 반복 (loop until the end of the sequence)


다음으로 for 반복문입니다. while 반복문이 조건(condition)이 참(True) 인 경우에 반복을 하는 반면에, for 반복문은 순서열(sequence)의 항목(item)을 처음부터 끝까지 순서대로 거쳐가면서 반복을 하게 됩니다. 




[Syntax of for loop statement in python]

for iterating_var in sequence:

    code block 


for 반복문은 'for' 다음에 '반복 변수(iterating_var)'를 지정해주고 'in' 다음에 순서열(sequence), 그리고 마지막에 '콜론(colon, :)을 써줍니다. 그리고 그 다음줄에 반복을 시킬 code block 을 써주면 되는데요, 이때 들여쓰기(indentation)을 해주어야 합니다. (IDE를 사용하면 자동으로 들여쓰기 해줌)



파이썬의 순서열에는 문자열(string), 튜플(tuple), 리스트(list), 사전(dictionary), Range 등이 있습니다. 


저는 특히 업무에서는 데이터 프레임을 만들어서 행(column)이나 열(row)의 개수를 세어서 range() 함수와 함께 for 반복문을 만들어서 자주 쓰곤 합니다. 



(2-1) for 반복문 : with Range


for 반복문과 함께 range(start, end, interval) 함수를 사용해서 'start' 부터 'end' 보다 작은 정수값을 'interval' 정수값 만큼 간격을 두고 증가하는 순서열을 만들어보겠습니다. 


range() 함수의 매개변수 start, end, interval 사용 시, 

 - 매개변수 'end' 의 순서열 항목은 포함이 되지 않으며,

   (아래 예제에서 range(0, 5, 1) 실행결과에서 '5'는 빠져있음. R 사용자가 헷갈리기 쉬우므로 주의 요망) 

 - 매개변수 'interval'로 순서열의 간격을 설정할 수 있으며, 

 - 매개변수 'interval'을 생략하면 순서열의 간격은 '1'이 디폴트이고, 

 - 매개변수 'start'을 생략하면 순서열은 '0'부터 디폴트로 시작하고, 

 - 정수만 인식하고 부동소수형(float)은 TypeError 가 발생합니다. 


 for i in range(start, end, interval)

실행 결과 (result) 

for i in range(0, 5, 1): # (start, end, interval)

    print(i)

0

1

2

3

4

for i in range(3, 10, 2):

    print(i)

3

5

7

9

for i in range(0, 5): # interval default : 1

    print(i)

0

1

2

3

4

for i in range(5): # start default : 0

    print(i)

0

1

2

3

4

for i in range(5, 5):

    print(i)

(no result)

# TypeError

for i in range(4.9, 5):

    print(i)

Traceback (most recent call last):


  File "<ipython-input-11-bb2a792a3440>", line 1, in <module>

    for i in range(4.9, 5):


TypeError: 'float' object cannot be interpreted as an integer



for 문을 복수번 사용하는 것도 가능합니다. 

for 반복문과 range() 함수를 두번 사용해서 1~5 사이의 정수에서 2개씩 뽑은 모든 조합 (즉, 5C2) 의 합을 구해보는 예제입니다. 


for i in range() 복수 반복문

실행 결과 (result) 

for i in range(1, 6):

    for j in range(i+1, 6):

        print(i, '+', j, '=', i+j)

1 + 2 = 3

1 + 3 = 4

1 + 4 = 5

1 + 5 = 6

2 + 3 = 5

2 + 4 = 6

2 + 5 = 7

3 + 4 = 7

3 + 5 = 8

4 + 5 = 9



(2-2) for 반복문 with 튜플(tuple)


파이썬의 순서열 중에서 이번에는 튜플(tuple)을 사용하여 for 반복문을 만들어보겠습니다. 튜플 안의 원소들을 하나씩 순회하면서 프린트를 해주는 코드입니다. 


for i in tuple

실행 결과 (result) 

for i in ('Python', 'is', 'easy'):

    print(i)


print('Really?')

Python

is

easy

Really?



바로 위의 예제와 동일한 결과를 반환하는 for loop 반복문을 range(len(tuple)) 과 tuple[index] 를 함께 사용하여 프로그래밍할 수도 있습니다. 위의 코드에 비하면 길기도 하고, 좀 복잡해 보이기도 하는데요, 만약 튜플의 길이가 길다면 아래의 방법으로 코딩하는 것이 더 깔끔할 수도 있으니 같이 알아 두시면 좋겠습니다. 


for loop with range() & tuple index

실행 결과 (result) 

# iterating by sequence index


mytuple = ('Python', 'is', 'easy')


for index in range(len(mytuple)):

    print(mytuple[index])


print('Really?')

Python

is

easy

Really? 



(2-3) for 반복문 with 리스트(list)


리스트도 순서열의 하나 이므로 위의 튜플 예제와 유사하게 for 반복문을 만들 수 있습니다. 리스트(list) 안에 있는 원소들을 순서대로 순회하면서 프린트하는 예제 코드입니다. 


for i in list

실행 결과 (result) 

for mylist in ['Python', 'is', 'easy']:

    print(mylist)


print('Are you sure?') 

Python

is

easy

Are you sure? 



(2-4) for 반복문 with 문자열(string)


문자의 순서열(sequence of character)인 문자열(string)도 마찬가지로 for 반복문이 가능합니다. 문자열의 개별 문자(character)와 공백(space) 하나 하나 별로 순회하면서 끝의 원소까지 프린트하는 예제 코드입니다. 


for i in string

실행 결과 (result) 

for mystr in ('Python is easy'):

    print(mystr)

print('--The end of string character--')

P

y

t

h

o

n

 

i

s

 

e

a

s

y

--The end of string character--



(2-5) for 반복문 with 사전(dictionary) & 튜플 분해(tuple unpacking)


사전(dictionary) 자료형의 경우는 dic.items()로 먼저 튜플 분해(tuple unpacking, 한글로 번역을 어케해야 할까요...? ^^;)를 해서 for 반복문에 사용하면 됩니다.  고객 ID와 이름의 짝(ID, Name pair)을 이룬 사전 자료형을 순서대로 프린트하도록 하는 for 반복문 예제입니다. 


for i in dictionary

실행 결과 (result) 

mydic = {'cust_01': 'kim'

            'cust_02': 'lee'

            'cust_03': 'choi'}


for key, val in mydic.items(): # tuple unpacking

    print("ID is '{0}' and NAME is '{1}'".format(key, val))

ID is 'cust_01' and NAME is 'kim'

ID is 'cust_02' and NAME is 'lee'

ID is 'cust_03' and NAME is 'choi'




3. continue: 조건이 참이면 반복문 계속 (continue loop if the condition is True)

     break: 조건이 참이면 반복문 중단 (stop loop if the condition is True)


(3-1) continue 반복 제어문


continue 는 조건이 참(True)일 때 continue 아래 부분의 code block 을 실행하지 않고 처음의 반복 부분으로 되돌아가서 반복 loop을 계속하도록 해줍니다. 


아래 예제는 for 반복문과 continue 반복 제어문을 사용해서 '1'부터 '5'까지의 정수로 이루어진 range 순서열에서 짝수(even number)이면 반복 문의 처음으로 되돌아가고, '홀수'(odd number)이면 프린트해주는 코드입니다. 


for 반복문 with continue 제어문

실행 결과 (result) 

# print only odd numbers b/w 1 ~ 5

for i in range(1, 6):

    if i % 2 == 0:

        continue

    

    print(i)

1

3

5



'1'부터 '5'까지의 정수로 이루어진 range 순서열에서 두 개의 정수를 조합(combination) 하여 합이 '5'인 경우만 프린트를 하게 해주는 코드를 for 반복문과 continue 반복 제어문을 사용해서 짜보았습니다. 


for 반복문 with continue 제어문

실행 결과 (result) 

# if i+j == 5 then print i, j combination

for i in range(1, 6):

    for j in range(i+1, 6):

        if i+j != 5:

            continue        


        print(i, '+', j, '=', i+j)

1 + 4 = 5

2 + 3 = 5



(3-2) break 반복 제어문


break 반복 제어문은 조건이 참(True)일 때 반복을 중단(break, stop) 시키는 역할을 합니다. 위의 continue 와는 정반대의 기능을 하는 것이지요. 


아래는 '1'부터 '6까지의 정수로 이루어진 range 수열을 순서대로 프린트를 반복하여 하되, 만약 '4'에 도달하면 중단(break)하라는 간단한 반복문 예제입니다. 


for 반복문 with break 제어문

실행 결과 (result) 

for i in range(1, 6):

    print(i)

    

    if i == 4:

        break

1

2

3

4




(3-3) for 반복문에 if, else 조건문과 break 반복 제어문 사용


아래 예제는 break 반복 제어문을 사용해서 '3~20'까지의 정수 중에서 '1'과 자기 자신 외에는 나누어지지 않는 정수인 소수(prime number) 를 찾아내는 프로그램 코드입니다. for 반복문, if, else 조건문, break 반복 제어문이 복합적으로 사용된, 좀 복잡한 코드입니다만, 지난번 포스팅과 이번 포스팅을 찬찬히 살펴보고 여기까지 따라오신 분이라면 충분히 이해하실 수 있을 것이라고 생각합니다. 


for 반복문 with break, if, else

실행 결과 (result) 

for i in range(3, 21):

    for j in range(2, i):

        if i % j == 0:

            k = i / j

            print("%d is %d * %d" %(i, j, k))

            break

        else:

            if j != i - 1:

                continue

            else:

                print(i, "is prime number.")

                break

print("The End")

3 is prime number.

4 is 2 * 2

5 is prime number.

6 is 2 * 3

7 is prime number.

8 is 2 * 4

9 is 3 * 3

10 is 2 * 5

11 is prime number.

12 is 2 * 6

13 is prime number.

14 is 2 * 7

15 is 3 * 5

16 is 2 * 8

17 is prime number.

18 is 2 * 9

19 is prime number.

20 is 2 * 10

The End



(3-4) nested while 반복문에 if 조건문과 break 반복 제어문 사용


nested while 반복문에 if 와 break를 사용해서 위의 (3-3)에서 했던 결과와 동일한 '3~20 사이의 소수 찾기' 를 해보겠습니다. 


nested while loops with break, if

실행 결과 (result) 

i = 3

while(i < 21):

    j = 2

    while(j <= (i/j)):

        if not(i%j): 

            print('%d is %d * %d' %(i, j, i/j))

            break

        

        j = j + 1

        

    if (j > i/j):

        print(i, " is prime")

        

    i = i + 1

    

print('The end')


# True or False?

# not(4%2) # True

# not(3%2) # False

3  is prime

4 is 2 * 2

5  is prime

6 is 2 * 3

7  is prime

8 is 2 * 4

9 is 3 * 3

10 is 2 * 5

11  is prime

12 is 2 * 6

13  is prime

14 is 2 * 7

15 is 3 * 5

16 is 2 * 8

17  is prime

18 is 2 * 9

19  is prime

20 is 2 * 10

The end


많은 도움이 되었기를 바랍니다. 


이번 포스팅이 도움이 되었다면 아래의 '공감~'를 꾸욱 눌러주세요.



728x90
반응형
Posted by Rfriend
,