728x90
728x170
구조화된 배열
- 구조화된 배열(Structured Array)은 ndarrays 를 의미한다.
- ndarrays의 데이터 타입은 시퀀스로 조직화된 단순한 데이터 타입인 필드를 모은 것
- 필드 : 구조화된 데이터 타입의 각 서브 타입에서 이름(string), 데이터 타입(dtype) 및 제목(title)
- ndarrays의 데이터 타입은 시퀀스로 조직화된 단순한 데이터 타입인 필드를 모은 것
예제
>>> arr = np.array([('jin', 25, 67), ('suho', 18, 77)], dtype=[('name', 'U10'), ('age', 'i4'), ('weight', 'f4')])
>>> arr
array([('jin', 25, 67.), ('suho', 18, 77.)],
dtype=[('name', '<U10'), ('age', '<i4'), ('weight', '<f4')])
- arr은 필드가 3개인 데이터 타입 구조이며 1차원 배열이다.
- 첫 번째 필드는 'name'이란 이름을 갖는 길이 10 이하의 문자열이다.
- 두 번째 필드는 'age'라는 이름을 갖는 32비트 정수이다.
- 세 번째 필드는 'weight'라는 이름의 32비트 실수이다.
- 구조화 배열 데이터 필드로의 접근 및 변경
>>> arr[1]
('suho', 18, 77.)
>>> arr['age'] = 20
>>> arr
array([('jin', 20, 67.), ('suho', 20, 77.)],
dtype=[('name', '<U10'), ('age', '<i4'), ('weight', '<f4')])
구조화된 데이터 타입
- 구조화된 데이터 타입(Structured Datatype)
- 요소 크기가 바이트 단위인 시퀀스
- 필드를 모아 놓은 것이라 할 수 있다.
- 각 필드 구조 안에는 이름, 데이터 타입 및 오프셋을 포함한다.
- 오프셋
- 필드 시작점에서의 위치를 바이트로 나타내는 속성
- 필드의 오프셋은 임의적이며 중첩될 수 있다.
- 보통 넘파이에 의해 자동으로 결정되지만, 직접 입력하여 설정할 수도 있다.
- 오프셋
구조화된 데이터 타입 생성
- numpy.dtype() 함수를 사용해 다음 4가지 형태로 구조화된 데이터 타입을 생성할 수 있다.
① 1개 필드를 1개의 튜플로 구성하는 튜플의 리스트 형태
- 각 튜플은 (필드 이름, 데이터 타입, shape) 구조를 가진다.
- 필드 이름 : 문자열(타이틀을 사용할 경우 튜플)
- 데이터 타입 : 데이터 타입으로 변경될 수 있는 객체
- shape : 서브 배열 shape를 나타내는 정수들의 튜플
>>> np.dtype([('a', 'f4'), ('b', np.float32), ('c', 'f4', (2, 2))])
dtype([('a', '<f4'), ('b', '<f4'), ('c', '<f4', (2, 2))])
- 필드 이름이 빈 문자열인(' ')이라면 기본 이름인 f#의 형태로 부여된다.
- # : 필드의 정수 인덱스이며, 왼쪽부터 0, 1, 2 순으로 번호가 부여됨.
>>> np.dtype([('a', 'f4'), ('', 'i4'), ('c', 'i8')])
dtype([('a', '<f4'), ('f1', '<i4'), ('c', '<i8')])
② 콤마로 구분하는 dtype 문자열 형태
- 필드의 바이트 오프셋과 itemsize는 자동으로 결정된다.
- 이때 필드 이름은 기본 이름인 f0, f1 등으로 부여된다.
>>> np.dtype('i8, f4, S3')
dtype([('f0', '<i8'), ('f1', '<f4'), ('f2', 'S3')])
>>> np.dtype('3int8, float32, (2, 3)float64')
dtype([('f0', 'i1', (3,)), ('f1', '<f4'), ('f2', '<f8', (2, 3))])
③ 필드 매개 변수 배열의 딕셔너리 형태
- 딕셔너리는 데이터 구조의 필드 바이트 오프셋과 itemsize를 조정할 수 있어 가장 유연한 형태이다.
- 딕셔너리는 2개의 필수 키인 names, formats와 4개의 옵션 키 offsets, itemsize, aligned 그리고 titles를 가진다.
- names와 formats 키의 값은 같은 길이인 각 필드 이름의 리스트다.
- 이 리스트는 데이터 타입 규격의 리스트여야 한다.
- offsets를 입력하지 않으면 자동으로 결정된다.
- 옵션 키 itemsize 값은 모든 필들르 충분히 포함할 수 있는 데이터 타입을 총 바이트 크기로 표시한 정수여야 한다.
- names와 formats 키의 값은 같은 길이인 각 필드 이름의 리스트다.
>>> np.dtype({'names': ['col1', 'col2'], 'formats': ['i4', 'f4']})
dtype([('col1', '<i4'), ('col2', '<f4')])
>>> np.dtype({'names': ['col1', 'col2'], 'formats': ['i4', 'f4'], 'offsets': [0, 4], 'itemsize': 12})
dtype({'names': ['col1', 'col2'], 'formats': ['<i4', '<f4'], 'offsets': [0, 4], 'itemsize': 12})
④ 필드 이름이 딕셔너리인 형태
- 딕셔너리의 키는 필드 이름이고 같은 타입과 오프셋으로 구성된 튜플이다.
>>> np.dtype({'col1': ('i1', 0), 'col2': ('f4', 1)})
dtype([('col1', 'i1'), ('col2', '<f4')])
- 구조화된 dtype에서 필드의 순서는 의미가 있다.
- 그러나 파이썬 딕셔너리가 순서를 고려하지 않으므로 앞과 같은 형태를 사용하는 것은 권장되지 않는다.
구조화된 데이터 타입 조작 및 표시
- dtype 객체의 names 속성을 이용하면 구조화된 데이터 타입에서 필드 이름의 튜플을 구할 수 있다.
>>> c = np.dtype([('a', 'i8'), ('b', 'f4')])
>>> c.names
('a', 'b')
- names 속성에 같은 길이의 문자열 시퀀스를 할당하면 필드 이름을 변경할 수 있다.
- dtype 객체는 딕셔너리 같은 속성 필드를 포함한다.
- 이 필드들의 키는 필드 이름이고, 값은 각 필드의 데이터 파일과 바이트 오프셋을 포함하는 튜플이다.
>>> c.fields
mappingproxy({'a': (dtype('int64'), 0), 'b': (dtype('float32'), 8)})
- 구조화되지 않은 배열에서 names와 fields 속성은 None과 같다.
자동 바이트 오프셋 및 정렬
- numpy.dtype의 키워드 인수
- align=True 를 입력할 경우
- 구조화된 데이터 타입의 필드 바이트 오프셋과 총 itemsize를 자동으로 결정한다.
- align=False 를 입력할 경우
- 넘파이는 이전 필드가 끝났던 바이트 오프셋에서 각 필드가 시작하도록 필드를 함께 팩(Pack)한다.
- 이때 필드는 메모리에서 인접해 있다.
- align=True 를 입력할 경우
>>> def print_offsets(d):
... print("offsets:", [d.fields[name][1] for name in d.names])
... print("itemsize:", d.itemsize)
...
>>> print_offsets(np.dtype('u1, u1, i4, u1, i8, u2'))
offsets: [0, 1, 2, 6, 7, 15]
itemsize: 17
- itemsize는 17 바이트이다.
- 오프셋은 정수값이며, 기준 바이트인 0에서 떨어져 있는 바이트 수다.
- 요소의 데이터 타입인 u1, u1, i4, u1, i8, u2는 메모리 인근에서 차례대로 0, 1, 2, 6, 7, 15 바이트 간격으로 배치되었다.
>>> d = np.dtype('u1, u1, i4, u1, i8, u2')
>>> d
dtype([('f0', 'u1'), ('f1', 'u1'), ('f2', '<i4'), ('f3', 'u1'), ('f4', '<i8'), ('f5', '<u2')])
>>> d.itemsize
17
>>> d.fields
mappingproxy({'f0': (dtype('uint8'), 0), 'f1': (dtype('uint8'), 1), 'f2': (dtype('int32'), 2), 'f3': (dtype('uint8'), 6), 'f4': (dtype('int64'), 7), 'f5': (dtype('uint16'), 15)})
>>> d.names
('f0', 'f1', 'f2', 'f3', 'f4', 'f5')
>>> d.fields['f0']
(dtype('uint8'), 0)
>>> d.fields['f0'][1]
0
- 많은 C 컴파일러가 C struct에 패드를 대는 것과 같이, 넘파이에서 align=True를 설정하면 구조에 패드를 댄다.
- "패드를 댄다."
- 예) 64비트 운영 체제에서 처리되는 단위 데이터의 특정 필드가 비어 있어 64비트에 맞지 않으면 64비트에 맞추기 위해 모자라는 비트를 덧붙이는 것
- 이 작업을 하지 않으면 동기화되지 않아 오류가 발생하거나 속도가 저하될 수 있다.
- "패드를 댄다."
- 구조를 정렬하여 데이터 타입 크기가 증가하면 성능을 향상시키는 경우도 있다.
- 각 필드 바이트 오프셋이 필드 정렬의 배수가 되도록 필드 사이에 삽입되는 패딩 바이트(Padding Byte)
- itemsize 가 가장 큰 필드 정렬의 배수가 되도록 더해진 뒷부분의 패드를 가진다.
print_offsets(np.dtype('u1, u1, i4, u1, i8, u2', align=True))
offsets: [0, 1, 4, 8, 16, 24]
itemsize: 32
- 딕셔너리 기반 데이터 타입에서는 offsets 키를 사용해 오프셋을 확인한다.
- align=True 를 설정하면 각 필드의 오프셋이 필드 크기의 배수이고, itemsize 가 가장 큰 필드 크기의 배수라는 것을 확인할 수 있다.
- 이러한 구조가 아니면 예외가 발생한다.
필드 제목
- 필드는 필드 이름 외에도 관련 제목, 추가 설명을 위해 사용하는 대체 이름 또는 필드에 대한 별칭을 가질 수 있다.
- 제목은 필드 이름과 같이 배열을 인덱싱하는 데 사용할 수 있다.
- 튜플 리스트형의 데이터 타입에서 제목을 추가할 때, 필드 이름은 하나의 문자열 대신 필드 제목과 필드 이름, 즉 2개 문자열인 튜플로 입력할 수 있다.
- 필드 속성에 접근하면 mappingproxy의 인수가 데이터 타입, 오프셋, 제목임을 확인할 수 있다.
>>> x = np.dtype([(('my title', 'name'), 'f4')])
>>> x.fields
mappingproxy({'name': (dtype('float32'), 0, 'my title'), 'my title': (dtype('float32'), 0, 'my title')})
>>> x.names
('name',)
- 딕셔너리 기반 형태를 사용할 때 titles 키를 이용해 필드 제목을 입력할 수 있다.
- 또한 (datatype, offset, title)처럼 3개 요소로 이루어진 튜플을 이용해 제목을 입력할 수 있다.
>>> np.dtype({'name': ('i4', 0, 'my title')})
dtype([(('my title', 'name'), '<i4')])
구조화된 배열 인덱싱 및 할당
- 구조화된 배열에 값을 할당하려면 파이썬 튜플, 스칼라 값 또는 다른 구조화된 배열을 이용하는 등 몇 가지 방법을 사용할 수 있다.
- 값을 할당하는 것은 동적으로 할당한다는 의미이며, 객체 지향 프로그래밍 언어에서 보편적으로 사용하는 개념이다.
파이썬 고유 타입인 튜플로 할당
- 구조화된 배열에 파이썬 튜플을 이용하여 값을 할당할 수 있다.
- 입력값은 배열에서 필드의 요소 수와 같은 길이의 튜플이어야 하며, 길이가 다르면 오류가 발생한다.
>>> a = np.array([(1, 2, 3), (4, 5, 6)], dtype='i8, f4, f8')
>>> a[1] = (7, 8, 9)
>>> a
array([(1, 2., 3.), (7, 8., 9.)],
dtype=[('f0', '<i8'), ('f1', '<f4'), ('f2', '<f8')])
스칼라 값으로 할당
- 구조화된 요소에 스칼라를 할당하면 모든 필드에 할당된다.
- 스칼라가 구조화된 배열에 할당되거나 구조화되지 않은 배열이 구조화된 배열로 할당될 때 이러한 결과가 발생한다.
>>> a = np.zeros(2, dtype='i8, f4, ?, S1')
>>> a
array([(0, 0., False, b''), (0, 0., False, b'')], // b : bytes 리터럴
dtype=[('f0', '<i8'), ('f1', '<f4'), ('f2', '?'), ('f3', 'S1')])
>>> a[:] = 7
>>> a
array([(7, 7., True, b'7'), (7, 7., True, b'7')],
dtype=[('f0', '<i8'), ('f1', '<f4'), ('f2', '?'), ('f3', 'S1')])
>>> a[:] = np.arange(2)
>>> a
array([(0, 0., False, b'0'), (1, 1., True, b'1')],
dtype=[('f0', '<i8'), ('f1', '<f4'), ('f2', '?'), ('f3', 'S1')])
다른 구조화된 배열로 할당
- 2개의 구조화된 배열 사이의 할당은 할당하는 쪽의 요소가 튜플로 변환된 다음, 받는 쪽에 할당되는 것처럼 발생한다.
- 예를 들어, 할당하는 배열의 첫 번째 필드는 받는 배열의 첫 번째 필드에 할당된다.
- 두 번째, 세 번째 필드 역시 이름과 관계없이 이러한 방식으로 할당된다.
- 구조화된 배열의 필드 개수가 각각 다르면 서로 할당될 수 없다.
>>> a = np.zeros(3, dtype=([('a', 'i8'), ('b', 'f4'), ('c', 'S3')]))
>>> b = np.ones(3, dtype=[('x', 'f4'), ('y', 'S3'), ('z', 'O')])
>>> b[:] = a
>>> b
array([(0., b'0.0', b''), (0., b'0.0', b''), (0., b'0.0', b'')],
dtype=[('x', '<f4'), ('y', 'S3'), ('z', 'O')])
인덱싱과 슬라이싱
- 표준 파이썬 구문인 x[obj]를 사용하면 배열 객체인 ndarrays를 인덱싱(Indexing) 할 수 있다.
- x : 배열
- obj : 선택하려는 인덱스
기본 인덱싱 구문
i : j : k
- i : 시작 인덱스
- j : 종료 인덱스
- k : 간격(Step), 표기하지 않으면 1로 간주됨.
- 배열 객체 내에서 첫 번째 요소는 인덱스 0, 다음 요소들은 순서대로 1씩 추가된다.
- i는 시작 인덱스, j - 1은 종료 인덱스
구문 유형 | 설명 |
arr[i:] | 배열의 인덱스 i부터 끝까지의 요소 선택 |
arr[i:j:k] | - i : 시작 인덱스, j - 1: 종료 인덱스, k : 간격(옵션) - 시작하는 인덱스 i부터 간격 k를 더하여 인덱스 j - 1까지의 요소를 선택 |
arr[:], arr[::] | 배열의 모든 요소를 선택 |
arr[::2] | 배열의 첫 번째 인덱스인 0부터 끝 요소까지 선택하되, 간격 2씩 더해서 마지막 요소 범위까지 선택 |
arr[-1] | 배열의 마지막 요소 |
arr[:-1] | - :를 중심으로 왼쪽은 공백이므로 첫 번째 요소이고, 오른쪽은 -1, 즉 j - 1이기 때문에 -2이다. - 첫 번째부터 끝에서 두 번째까지의 요소를 선택 |
arr[-2:] | 배열의 끝에서 두 번째부터 배열의 마지막 요소까지 선택 |
arr[:-2] | 배열의 처음부터 끝에서 세 번째까지의 요소를 선택 |
arr[::-1] | 배열의 모든 요소를 마지막 요소부터 첫 번째 요소까지 역순으로 선택 |
arr[1::-1] | 인덱스 1부터 마지막 요소를 선택하되, 간격이 -1로 역순이 되므로 두 번째 요소와 첫 번째 요소를 차례로 선택 |
arr[-3::-1] | 배열의 끝에서 세 번째 요소부터 마지막 요소까지를 선택하되, 간격이 -1이므로 역순으로 선택 |
배열 객체 요소 선택
- 파이썬 리스트에서 요소를 선택하는 것과 같이 다차원 배열에서 요소를 간단한게 선택할 수 있다.
>>> arr1 = np.arange(10)
>>> arr1
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> arr1[1]
1
- 2차원 배열 객체에서 요소를 선택하려면 인수 2개를 사용한다.
- 첫 번째 인수 : 행
- 두 번째 인수 : 열
>>> arr2 = np.arange(9).reshape(3, 3)
>>> arr2
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> arr2[2, 1]
7
- 3차원 배열 객체에서는 인수 3개를 사용하여 요소를 선택한다.
- 첫 번째 인수 : 면
- 두 번째 인수 : 행
- 세 번째 인수 : 열
>>> arr3 = np.reshape(np.arange(24), (2, 3, 4))
>>> arr3
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
>>> arr3[1, 1, 2]
18
>>> arr3[1][2][3]
23
기본 인덱싱과 슬라이싱
- [start:stop:step] 으로 구성된 slice 객체, 정수, slice 객체와 정수의 튜플 등을 이용해 기본 슬라이싱(Slicing)을 실행할 수 있다.
- 정수 인덱스를 처리하는 가장 간단한 방법은 배열 스칼라를 반환하는 것이다.
- 기본 인덱싱 처리로 생성되는 모든 배열은 항상 원본 배열의 뷰(View)이다.
- 뷰(View) : 원본 배열 객체를 인덱싱하여 자른 후 생성된 배열
배열 샘플 생성
>>> arr1 = np.arange(10)
>>> arr1
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> arr2 = np.arange(9).reshape(3, 3)
>>> arr2
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> arr3 = np.reshape(np.arange(24), (2, 3, 4))
>>> arr3
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
arr1 | |||||||||
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
-10 | -9 | -8 | -7 | -6 | -5 | -4 | -3 | -2 | -1 |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
arr2 | ||
0 | 1 | 2 |
3 | 4 | 5 |
6 | 7 | 8 |
arr3 | ||||||||
0 | 1 | 2 | 3 | 12 | 13 | 14 | 15 | |
4 | 5 | 6 | 7 | 16 | 17 | 18 | 19 | |
8 | 9 | 10 | 11 | 20 | 21 | 22 | 23 |
예제
>>> arr1[1]
1
>>> arr1[:6]
array([0, 1, 2, 3, 4, 5])
>>> arr1[0:5]
array([0, 1, 2, 3, 4])
>>> arr1[::2]
array([0, 2, 4, 6, 8])
>>> arr1[1::2]
array([1, 3, 5, 7, 9])
>>> arr1[1:7:2]
array([1, 3, 5])
- i가 0인 경우 -1이 배열의 맨 끝 요소이므로 인덱스에 -1씩 추가하여 처리하고, j에는 -1을 추가한다.
>>> arr1[-3:9]
array([7, 8])
>>> arr1[:-3]
array([0, 1, 2, 3, 4, 5, 6])
>>> arr1[-3:2:-1]
array([7, 6, 5, 4, 3])
- 인덱스 시작이 종료보다 크면 길이가 0인 객체가 반환된다.
>>> arr1[5:2]
array([], dtype=int32)
- [i:] 표기는 :를 중심으로 i가 인덱스의 시작이고 종료의 공백 표기는 배열의 요소 끝까지 인덱스 범위를 설정하여 처리하겠다는 의미이다.
>>> arr1[5:]
array([5, 6, 7, 8, 9])
>>> arr2[1:]
array([[3, 4, 5],
[6, 7, 8]])
- 2차원 배열 arr2의 인덱스처럼 축을 1개만 설정하면 인덱스 범위는 행에만 적용된다.
- 배열 arr2 의 요소에서 특정 범위를 인덱싱하면 0축인 행과 1축인 열에 각각 슬라이싱을 실행할 수 있다.
>>> arr2
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> arr2[:2, :2]
array([[0, 1],
[3, 4]])
>>> arr2[:, ::-1]
array([[2, 1, 0],
[5, 4, 3],
[8, 7, 6]])
- 2차원 배열을 슬라이싱할 때 0축이나 1축 중 하나에 정수를 입력하면 2차원이 1차원으로 낮아지고, 축 2개에 정수를 입력하면 스칼라가 된다.
>>> arr2[:, :]
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> arr2[1, :]
array([3, 4, 5])
>>> arr2[1, 2]
5
- 다음 예제의 arr3[0, :, 1]은 3차원 배열인 arr3을 0면, 모든 행, 1열을 선택한 배열로 인덱싱한다.
- 이때 0과 1, 즉 정수가 2개 사용되었으므로 3차원 배열 객체가 1차원 배열 객체가 된다는 점에 유의한다.
- arr3[1, :, :]은 정수가 1개 적용되었으므로 2차원 배열 객체가 된다.
>>> arr3
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
>>> arr3[0, :, 1]
array([1, 5, 9])
>>> arr3[1, :, :]
array([[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]])
- 다음 예제에서 3차원 배열 arr3을 인덱싱할 때 :2는 0면과 1면, 1:은 2행과 3행 그리고 :2는 0열과 1열을 선택해 슬라이싱한다.
>>> arr3[:2, 1:, :2]
array([[[ 4, 5],
[ 8, 9]],
[[16, 17],
[20, 21]]])
고급 인덱싱
- 고급 인덱싱(Advanced Indexing)은 x[obj] 에서 선택 객체인 obj가 튜플 시퀀스 객체가 아니거나 데이터 타입 정수 또는 불리언의 ndarray일 때 사용할 수 있다.
- 기본 인덱싱은 뷰를 반환하지만, 고급 인덱싱은 항상 데이터의 복사본을 반환한다.
- 고급 인덱싱을 할 때 배열의 각 행에서 특정 요소를 선택해야 한다.
>>> arr = np.array([[1, 2], [3, 4], [5, 6]])
>>> arr
array([[1, 2],
[3, 4],
[5, 6]])
>>> arr[[0, 1, 2], [0, 1, 0]]
array([1, 4, 5])
- 배열 arr 에서 행 인덱스 [0, 1, 2]로 전체 행을 선택하였다.
- 그리고 행 인덱스는 열 인덱스 [0, 1, 0]에 일대일로 매핑된다.
- 결국 0행 0열, 1행 1열, 2행 0열이 반환된다.
- 그리고 행 인덱스는 열 인덱스 [0, 1, 0]에 일대일로 매핑된다.
- 기본 슬라이싱과 비슷한 기능을 실행하기 위해 브로드캐스팅(Broadcasting)을 사용할 수 있다.
- 브로드캐스팅 : 더 작은 배열이 커다란 배열의 행과 열에 호환되도록 확대하는 것
- 고급 인덱싱을 사용하면 다음처럼 4×3 배열 객체에서 행과 열을 각각 선택해 요소들을 처리할 수도 있다.
>>> arr = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])
>>> rows = np.array([[0, 0], [3, 3]], dtype=np.intp)
>>> columns = np.array([[0, 2], [0, 2]], dtype=np.intp)
>>> arr[rows, columns]
array([[ 0, 2],
[ 9, 11]])
- 넘파이는 약간의 상수들을 포함한다.
- numpy.newaxis
- 함수가 아닌 상수
- None의 별칭으로써 인덱싱할 때 유용하다.
- 1차원 배열을 2차원으로, 2차원 배열을 3차원으로 차원을 1개씩 증가시킬 수 있다.
>>> np.newaxis is None
True
>>> arr = np.arange(25).reshape(5, 5)
>>> arr.shape
(5, 5)
>>> arr_3d = arr[np.newaxis]
>>> arr_3d.shape
(1, 5, 5)
- 또한 상수 newaxis는 1차원 배열을 행 벡터나 열 벡터로 변환할 수 있다.
>>> arr = np.arange(10)
>>> arr.shape
(10,)
>>> arr_row = arr[np.newaxis, :]
>>> arr_row.shape
(1, 10)
>>> arr_col = arr[:, np.newaxis]
>>> arr_col.shape
(10, 1)
- 다음은 numpy.newaxis 를 사용하여 차원을 증가시켜 연산하는 예제이다.
>>> arr = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])
>>> rows = np.array([0, 3], dtype=np.intp)
>>> columns = np.array([0, 2], dtype=np.intp)
>>> rows[:, np.newaxis]
array([[0],
[3]], dtype=int64)
>>> arr[rows[:, np.newaxis], columns]
array([[ 0, 2],
[ 9, 11]])
- 다음은 인덱스에 사용하는 배열과 스칼라 값으로 인덱싱한다.
- 이때 스칼라 값의 인덱스가 모든 요소에 전파된다는 의미에서 브로드캐스팅이라 한다.
>>> arr = np.arange(15).reshape(3, 5)
>>> arr
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
>>> arr[np.array([0, 2]), 3]
array([ 3, 13])
- 배열의 shape가 같지 않으면 브로드캐스팅을 할 수 없다.
- 이때 newaxis를 사용해 차원을 증가시키면 배열 shape를 동일하게 만들 수 있다.
>>> arr1 = np.array([1, 2, 3, 4, 5])
>>> arr2 = np.array([11, 12, 13])
>>> arr1 + arr2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: operands could not be broadcast together with shapes (5,) (3,)
>>> arr1_nx = arr1[:, np.newaxis]
>>> arr2_nx = arr2[:, np.newaxis]
>>> arr1_nx
array([[1],
[2],
[3],
[4],
[5]])
>>> arr2_nx
array([[11],
[12],
[13]])
>>> arr1_nx + arr2
array([[12, 13, 14],
[13, 14, 15],
[14, 15, 16],
[15, 16, 17],
[16, 17, 18]])
>>> arr2_nx + arr1
array([[12, 13, 14, 15, 16],
[13, 14, 15, 16, 17],
[14, 15, 16, 17, 18]])
- arr1과 arr2의 shape가 같지 않아 arr1 + arr2 연산에서 오류가 발생했다.
- 따라서 연산이 가능하도록 arr1_nx와 arr2_nx의 차원을 하나 증대시켜 2개의 배열을 서로 더하면 열이 확대되는 브로드캐스팅을 할 수 있다.
불리언 배열로 인덱싱
- 넘파이에서는 배열 객체의 고급 인덱싱을 위해 불리언 값을 인덱스로 사용할 수 있다.
- 원하는 요소와 원하지 않는 요소를 명시적으로 선택하는 필터링을 할 수 있다.
- 예) 배열의 차원과 같은 shape를 가지는 불리언 배열을 인덱스로 사용하면, 행으로 처리된 1차원 배열을 반환한다.
- 원하는 요소와 원하지 않는 요소를 명시적으로 선택하는 필터링을 할 수 있다.
>>> arr = np.arange(12).reshape(3, 4)
>>> arr
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>> ind = arr>5
>>> ind
array([[False, False, False, False],
[False, False, True, True],
[ True, True, True, True]])
>>> arr[ind]
array([ 6, 7, 8, 9, 10, 11])
- 불리언 배열을 2차원 배열의 인덱스 배열로 사용하면 2차원 배열을 반환한다.
>>> ind[:, 1]
array([False, False, True])
>>> arr[ind[:, 1]]
array([[ 8, 9, 10, 11]])
- 2차원 불리언 배열로 3차원 배열을 인덱싱하면 2차원 배열을 반환한다.
>>> arr = np.arange(24).reshape(2, 3, 4)
>>> arr
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
>>> ind = np.array([[True, False, True], [False, True, False]])
>>> arr[ind]
array([[ 0, 1, 2, 3],
[ 8, 9, 10, 11],
[16, 17, 18, 19]])
- (2, 3)의 2차원 불리언 배열로, shape가 (2, 3, 4)인 3차원 배열을 인덱싱한 결과로써 shape가 (3, 4)인 2차원 배열이 된다.
슬라이싱과 인덱스 배열 처리
- 인덱스는 슬라이싱과 함께 사용할 수 있다.
>>> arr = np.arange(12).reshape(3, 4)
>>> arr[np.array([1, 2]), 1:3]
array([[ 5, 6],
[ 9, 10]])
- 또한 브로드캐스팅된 불리언 인덱스와 함께 슬라이싱을 실행할 수 있다.
>>> ind = arr > 5
>>> ind
array([[False, False, False, False],
[False, False, True, True],
[ True, True, True, True]])
>>> ind[:, 2]
array([False, True, True])
>>> arr[ind[:, 2], 1:3]
array([[ 5, 6],
[ 9, 10]])
인덱스를 반환하는 numpy.nonzero(), numpy.transpose() 함수
- numpy.nonzero() 함수
- 0이 아닌 요소의 인덱스들을 반환하여 numpy.ndarray.nonzero 를 실행한 것과 같은 결과를 반환한다.
- 각 배열의 차원에서 0이 아닌 요소의 인덱스를 포함하는 튜플을 반환한다.
>>> arr = np.array([[1, 0, 0], [0, 2, 0], [1, 1, 0]])
>>> arr
array([[1, 0, 0],
[0, 2, 0],
[1, 1, 0]])
>>> np.nonzero(arr)
(array([0, 1, 2, 2], dtype=int64), array([0, 1, 0, 1], dtype=int64))
- 0이 아닌 요소의 인덱스 : [0, 0], [1, 1], [2, 0], [2, 1]
- [0, 1, 2, 2] : 0이 아닌 값들의 첫 번째 인덱스 모음
- [0, 1, 0, 1] : 0이 아닌 튜플의 두 번째 인덱스 모음
>>> arr[np.nonzero(arr)]
array([1, 2, 1, 1])
>>> np.transpose(np.nonzero(arr))
array([[0, 0],
[1, 1],
[2, 0],
[2, 1]], dtype=int64)
- 배열의 요소가 0이 아닌 값들을 정렬한다.
- 축을 바꾸는 전치 함수 numpy.transpose() 를 사용하면 배열에서 0이 아닌 값을 나타내는 인덱스들을 그룹으로 처리할 수 있다.
>>> arr = np.arange(9).reshape(3, 3)
>>> arr > 3
array([[False, False, False],
[False, True, True],
[ True, True, True]])
>>> np.nonzero(arr > 3)
(array([1, 1, 2, 2, 2], dtype=int64), array([1, 2, 0, 1, 2], dtype=int64))
- nonzero() 함수에 불리언 조건을 적용해 True인 인덱스를 반환하게 할 수 있다.
>>> (arr > 3).nonzero()
(array([1, 1, 2, 2, 2], dtype=int64), array([1, 2, 0, 1, 2], dtype=int64))
- 불리언 배열에 nonzero() 메소드를 적용해도 같은 결과를 반환한다.
- numpy.transpose() 함수
- 배열의 축을 변환하여 뷰를 반환한다.
>>> arr = np.arange(4).reshape((2, 2))
>>> arr
array([[0, 1],
[2, 3]])
>>> np.transpose(arr)
array([[0, 2],
[1, 3]])
>>> arr1 = np.ones((1, 2, 3))
>>> np.transpose(arr1, (1, 0, 2)).shape
(2, 1, 3)
- 2차원 배열인 arr을 전치하면 행이 열로, 열이 행으로 축이 변환된다.
- 3차원 배열 arr1의 shape는 (1, 2, 3)이다.
- 축은 0축, 1축, 2축 순서인데 이것을 1축, 0축, 2축 순서로 전치 처리하면 shape (2, 1, 3)을 반환한다.
- 1차원 배열은 전치하면 원본 배열과 같은 뷰를 반환한다.
- 전치 처리는 3가지 형태로 할 수 있다.
- numpy.ndarray.T 속성을 이용하는 arr.T 형태
- np.transpose(arr) 함수를 사용하는 방법
- arr.transpose() 함수를 사용하는 방법
>>> a = [1, 2, 3]
>>> a
[1, 2, 3]
>>> arr = np.array([a])
>>> b = np.array(a)
>>> b.T
array([1, 2, 3])
>>> arr.transpose()
array([[1],
[2],
[3]])
다차원 배열 전치
>>> arr = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
>>> arr
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
>>> arr.transpose()
array([[1, 5],
[2, 6],
[3, 7],
[4, 8]])
>>> arr1 = np.array([[[0, 1, 2, 3], [4, 5, 6, 7]], [[8, 9, 10, 11], [12, 13, 14, 15]]])
>>> arr1
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7]],
[[ 8, 9, 10, 11],
[12, 13, 14, 15]]])
>>> arr1.T
array([[[ 0, 8],
[ 4, 12]],
[[ 1, 9],
[ 5, 13]],
[[ 2, 10],
[ 6, 14]],
[[ 3, 11],
[ 7, 15]]])
- 배열 arr은 0축인 행 2개, 1축인 열 4개를 가진 2차원 배열이다.
- 전치하면 배열의 각 첫 번째 요소끼리 그룹화한 다음 두 번째 요소끼리 그룹화한다.
- 3차원 배열 arr1은 0축인 면이 2개, 1축인 행이 2개, 2축인 열이 4개로 구성되어 있다.
- 전치하면 shape가 (4, 2, 2)가 된다.
- 다음으로 배열 arr1을 축이 (1, 0, 2)가 되도록 전치 처리해본다.
- 0축과 1축을 바꾸고, 2축을 그대로 두는 전치
- 이 경우, 면과 행은 변동되고 열이 변동되지 않으므로 전치 처리해도 형태는 같다.
>>> arr2 = np.transpose(arr1, (1, 0, 2))
>>> arr3 = arr1.transpose((1, 0, 2))
>>> arr2
array([[[ 0, 1, 2, 3],
[ 8, 9, 10, 11]],
[[ 4, 5, 6, 7],
[12, 13, 14, 15]]])
>>> arr3
array([[[ 0, 1, 2, 3],
[ 8, 9, 10, 11]],
[[ 4, 5, 6, 7],
[12, 13, 14, 15]]])
- arr2와 arr3의 결과는 같다.
- 0축과 1축을 바꾸는 전치 처리 식을 알기 쉽게 표현하면 다음 그림과 같다.
- 그림에서 2면의 첫 번째 행이 1면의 두 번째 행으로 이동한 것에 주목하자.
- arr1.T 속성을 사용하면 축 (0, 1, 2)가 (2, 1, 0)으로 전치된다.
- 1축은 변화가 없고, 0축과 2축이 서로 교환되어 면이 4개 생긴다.
>>> arr4 = arr1.T
>>> arr4
array([[[ 0, 8],
[ 4, 12]],
[[ 1, 9],
[ 5, 13]],
[[ 2, 10],
[ 6, 14]],
[[ 3, 11],
[ 7, 15]]])
예: 전치한 arr1, arr2, arr3, arr4 의 shape 확인하기
>>> arr1.shape
(2, 2, 4)
>>> arr2.shape
(2, 2, 4)
>>> arr3.shape
(2, 2, 4)
>>> arr4.shape
(4, 2, 2)
유니버셜 함수(Universal Function, ufunc)
- 유니버셜 함수(Universal Function, ufunc)
- 스칼라로 연산하는 수학적 함수들
- 인터페이스를 제공하는 벡터화된 래퍼(Wrappers)
- 래퍼(Wrapper) : 계산을 최소화하고 시스템을 호출할 수 있는 객체
- 벡터화 : 데이터 타입이 정형화되었거나 실행 프로세스가 컴파일된 것
- 실행 절차를 축약해 프로그램이 쉽게 처리되도록 하는 인터페이스들을 포함한다.
- 예) 파이썬에서 반복문(Loop)으로 배열 데이터 요소에 다양한 연산을 실행할 때 처리 속도가 매우 느리므로 속도 개선을 위해 넘파이에서 새로운 인터페이스를 제공한다.
class numpy.ufunc
- 유니버셜 함수는 함수를 실행하기 위해 numpy.func 클래스를 인스턴스한다.
- ufunc 클래스는 유용한 속성과 메소드를 가지고 있다.
- 모든 ufunc는 요소 단위로 배열을 연산하고 브로드캐스팅한다.
- 유너버셜 함수를 사용하면 입력이 1개인 단항 연산과 입력이 2개인 이항 연산을 할 수 있다.
- 유니버셜 함수는 속성을 가지고 있으나, 속성을 직접 설정할 수는 없다.
유니버셜 함수의 속성
속성 종류 | 기능 |
__doc__ | ufunc의 docstring |
__name__ | ufunc의 name |
ufunc.nin | 입력 수 |
ufunc.nout | 출력 수 |
ufunc.nargs | 인수(Argument) 수 |
ufunc.ntypes | 타입 수 |
ufunc.types | 입력에서 출력으로 그룹화된 타입의 리스트를 반환 |
ufunc.identity | identity 값 |
ufunc.signature | 일반화된 ufunc가 연산하는 중심 요소 정의 |
- 유니버셜 함수가 취급하는 입력 및 출력 인수 개수를 포함하는 데이터 속성 확인하기
>>> np.add.nin
2
>>> np.add.nout
1
>>> np.exp.nin
1
>>> np.exp.nout
1
- 모든 ufunc는 reduce(), accumulate(), reduceat()와 outer() 메소드를 가진다.
- 이들 메소드는 2개 인수를 입력하고 1개 출력을 반환하는 스칼라 ufunc에서 사용할 수 있다.
- at() 메소드는 고급 인덱싱을 사용할 때 연산이 제 위치에서 실행되도록 한다.
유니버셜 함수의 메소드
메소드 종류 | 기능 |
reduce(a[, axist, dtype, out, keepdims]) | 한 축을 따라 ufunc를 적용하여 a의 차원을 1개씩 축소한다. |
accumulate(a[, axis, dtype, out]) | 모든 요소에 연산자를 적용한 결과를 축적한다. |
reduceat(a, indices[, axist, dtype, out]) | 특정 슬라이싱 기능인 reduce를 단일 축에 실행한다. |
outer(A, B, **kwargs) | A에 a, B에 b인 모든 쌍(a, b)에 유니버셜 함수 연산인 ufunc op를 적용한다. |
at(a, indices[, b]) | 인덱스로 명시된 요소의 위치에서 a에 버퍼 없이(unbuffered) 바로 연산을 실행한다. |
- 유니버셜 함수는 단항 또는 이항 인수를 가지며, 호출할 수 있는 객체이다.
>>> np.add([1, 2, 3, 4, 5], [1, 2, 3, 4, 5])
array([ 2, 4, 6, 8, 10])
>>> arr = np.array([1, 2, 3, 4, 5])
>>> np.add.reduce(arr)
15
- ufunc의 reduce() 메소드는 arr 시퀀스를 인수로 가지고 호출되고, 시퀀스의 요소에 대해 ufunc인 add()가 실행되어 차원이 1차원에서 0차원으로 감소된다.
- 1차원 이상 배열 객체에 reduce() 메소드를 적용하면 기본 축인 0축에 감소를 실행한다.
>>> arr = np.array(([1, 2, 3], [4, 5, 6]))
>>> arr
array([[1, 2, 3],
[4, 5, 6]])
>>> np.add.reduce(arr)
array([5, 7, 9])
>>> np.add.reduce(arr, axis=1)
array([ 6, 15])
- 행 2개가 1개로 축소되면서 2차원이 1차원으로 감소한다.
- axis=1 옵션을 설정하면 열 축에 감소를 적용하고, 열 3개가 2개로 줄어들면서 1차원으로 감소한다.
- 유니버셜 함수 add()의 reduce() 메소드를 3차원 배열에 적용하면 2차원 배열이 되고, 2차원 배열에 적용하면 1차원 배열이 된다. 1차원 배열에 적용하면 요소의 값을 합산한 스칼라 값이 된다.
>>> np.add.reduce(np.array([[[1, 2, 3, 4, 5]]]))
array([[1, 2, 3, 4, 5]])
>>> np.add.reduce(np.array([[1, 2, 3, 4, 5]]))
array([1, 2, 3, 4, 5])
>>> np.add.reduce(np.array([1, 2, 3, 4, 5]))
15
- 유니버셜 함수 add()의 accumulate() 메소드는 모든 배열 요소에 연산자를 적용한 결과를 누계한다.
- 유니버셜 함수 add()에 각각 accumulate() 메소드를 연산한 결과는 다음과 같다.
>>> np.add.accumulate([1, 2, 3, 4, 5])
array([ 1, 3, 6, 10, 15])
>>> np.multiply.accumulate([1, 2, 3, 4, 5])
array([ 1, 2, 6, 24, 120])
- 2차원 배열에 accumulate() 메소드 연산을 수행하면 기본 축인 0축이 감소된다.
- axis=1로 옵션을 설정하면 열 축에 연산을 실행한다.
>>> arr = np.arange(12).reshape((3, 4))
>>> np.add.accumulate(arr)
array([[ 0, 1, 2, 3],
[ 4, 6, 8, 10],
[12, 15, 18, 21]])
>>> np.add.accumulate(arr, axis=1)
array([[ 0, 1, 3, 6],
[ 4, 9, 15, 22],
[ 8, 17, 27, 38]])
- ufunc의 reduceat() 메소드는 단일 축에 슬라이싱을 실행한다.
- 두 번째 인수인 인덱스는 len(arr)-1 이하인 수여야 한다.
>>> arr = np.arange(7)
>>> arr
array([0, 1, 2, 3, 4, 5, 6])
>>> np.add.reduceat(arr, [0, 3, 5, 6])
array([3, 7, 5, 6])
- 배열 arr에서 arr[0:3], [3:5], [5:6], [6:]에 해당하는 요소를 각각 더한 값을 반환한다.
>>> np.linspace(0, 15, 16)
array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12.,
13., 14., 15.])
>>> arr = np.linspace(0, 15, 16).reshape(4, 4)
>>> arr
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.]])
>>> np.add.reduceat(arr, [0, 3, 1, 2, 0])
array([[12., 15., 18., 21.],
[12., 13., 14., 15.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[24., 28., 32., 36.]])
- 4개의 행으로 구성한 배열 arr에 np.add.reduceat을 실행해 1행+2행+3행, 4행, 2행, 3행, 1행+2행+3행+4행을 연산해 총 5개의 배열 행이 생성되도록 처리한다.
- arr[0:3], [1:2], [2:0], arr[0:]의 범위를 인덱스를 설정한다.
- ufunc의 outer() 메소드는 배열 A에서 a, 배열 B에서 b를 가지는 모든 쌍인 (a, b)에 ufunc op를 적용한다.
- M=A.ndim, N=B.ndim이라고 할 때 op.outer(A, B)의 결과 C는 차원이 M+N인 배열이다.
>>> np.multiply.outer([1, 2, 3], [4, 5, 6])
array([[ 4, 5, 6],
[ 8, 10, 12],
[12, 15, 18]])
- 다음과 같이 다차원 배열에 out() 메소드를 적용할 수 있다.
>>> arr1 = np.array([[1, 2, 3], [4, 5, 6]])
>>> arr1.shape
(2, 3)
>>> arr2 = np.array([[1, 2, 3, 4]])
>>> arr2.shape
(1, 4)
>>> arr = np.multiply.outer(arr1, arr2)
>>> arr.shape; arr
(2, 3, 1, 4)
array([[[[ 1, 2, 3, 4]],
[[ 2, 4, 6, 8]],
[[ 3, 6, 9, 12]]],
[[[ 4, 8, 12, 16]],
[[ 5, 10, 15, 20]],
[[ 6, 12, 18, 24]]]])
유용한 유니버셜 함수
- 넘파이에 정의된 60개 이상의 유니버셜 함수들을 이용해 다양한 연산을 수행할 수 있다.
- 예를 들어 add(a, b)를 사용하는 것과 같이, 배열에서 여러 ufunc를 자동으로 호출할 수 있다.
- a와 b는 ndarray 객체이다.
수학 연산을 위한 유니버셜 함수
함수 | 설명 |
add(x1, x2, /[, out, where, casting, order, ...]) | Add arguments element-wise. |
subtract(x1, x2, /[, out, where, casting, ...]) | Subtract arguments, element-wise. |
multiply(x1, x2, /[, out, where, casting, ...]) | Multiply arguments element-wise. |
matmul(x1, x2, /[, out, casting, order, ...]) | Matrix product of two arrays. |
divide(x1, x2, /[, out, where, casting, ...]) | Returns a true division of the inputs, element-wise. |
logaddexp(x1, x2, /[, out, where, casting, ...]) | Logarithm of the sum of exponentiations of the inputs. |
logaddexp2(x1, x2, /[, out, where, casting, ...]) | Logarithm of the sum of exponentiations of the inputs in base-2. |
true_divide(x1, x2, /[, out, where, ...]) | Returns a true division of the inputs, element-wise. |
floor_divide(x1, x2, /[, out, where, ...]) | Return the largest integer smaller or equal to the division of the inputs. |
negative(x, /[, out, where, casting, order, ...]) | Numerical negative, element-wise. |
positive(x, /[, out, where, casting, order, ...]) | Numerical positive, element-wise. |
power(x1, x2, /[, out, where, casting, ...]) | First array elements raised to powers from second array, element-wise. |
float_power(x1, x2, /[, out, where, ...]) | First array elements raised to powers from second array, element-wise. |
remainder(x1, x2, /[, out, where, casting, ...]) | Returns the element-wise remainder of division. |
mod(x1, x2, /[, out, where, casting, order, ...]) | Returns the element-wise remainder of division. |
fmod(x1, x2, /[, out, where, casting, ...]) | Returns the element-wise remainder of division. |
divmod(x1, x2[, out1, out2], / [[, out, ...]) | Return element-wise quotient and remainder simultaneously. |
absolute(x, /[, out, where, casting, order, ...]) | Calculate the absolute value element-wise. |
fabs(x, /[, out, where, casting, order, ...]) | Compute the absolute values element-wise. |
rint(x, /[, out, where, casting, order, ...]) | Round elements of the array to the nearest integer. |
sign(x, /[, out, where, casting, order, ...]) | Returns an element-wise indication of the sign of a number. |
heaviside(x1, x2, /[, out, where, casting, ...]) | Compute the Heaviside step function. |
conj(x, /[, out, where, casting, order, ...]) | Return the complex conjugate, element-wise. |
conjugate(x, /[, out, where, casting, ...]) | Return the complex conjugate, element-wise. |
exp(x, /[, out, where, casting, order, ...]) | Calculate the exponential of all elements in the input array. |
exp2(x, /[, out, where, casting, order, ...]) | Calculate 2**p for all p in the input array. |
log(x, /[, out, where, casting, order, ...]) | Natural logarithm, element-wise. |
log2(x, /[, out, where, casting, order, ...]) | Base-2 logarithm of x. |
log10(x, /[, out, where, casting, order, ...]) | Return the base 10 logarithm of the input array, element-wise. |
expm1(x, /[, out, where, casting, order, ...]) | Calculate exp(x) - 1 for all elements in the array. |
log1p(x, /[, out, where, casting, order, ...]) | Return the natural logarithm of one plus the input array, element-wise. |
sqrt(x, /[, out, where, casting, order, ...]) | Return the non-negative square-root of an array, element-wise. |
square(x, /[, out, where, casting, order, ...]) | Return the element-wise square of the input. |
cbrt(x, /[, out, where, casting, order, ...]) | Return the cube-root of an array, element-wise. |
reciprocal(x, /[, out, where, casting, ...]) | Return the reciprocal of the argument, element-wise. |
gcd(x1, x2, /[, out, where, casting, order, ...]) | Returns the greatest common divisor of |x1| and |x2| |
lcm(x1, x2, /[, out, where, casting, order, ...]) | Returns the lowest common multiple of |x1| and |x2| |
- numpy.subtract() 함수 사용 예
>>> np.subtract(1.0, 4.0)
-3.0
>>> arr1 = np.arange(9).reshape((3, 3))
>>> arr2 = np.arange(3.0)
>>> np.subtract(arr1, arr2)
array([[0., 0., 0.],
[3., 3., 3.],
[6., 6., 6.]])
- numpy.power() 함수 사용 예
>>> arr1 = range(6)
>>> arr1
range(0, 6)
>>> np.power(arr1, 3)
array([ 0, 1, 8, 27, 64, 125], dtype=int32)
>>> arr2 = [1.0, 2.0, 3.0, 3.0, 2.0, 1.0]
>>> np.power(arr1, arr2)
array([ 0., 1., 8., 27., 16., 5.])
- 유니버셜 함수에 브로드캐스팅을 적용할 수 있다.
>>> arr3 = np.array([[1, 2, 3, 3, 2, 1], [1, 2, 3, 3, 2, 1]])
>>> arr3
array([[1, 2, 3, 3, 2, 1],
[1, 2, 3, 3, 2, 1]])
>>> np.power(arr1, arr3)
array([[ 0, 1, 8, 27, 16, 5],
[ 0, 1, 8, 27, 16, 5]])
삼각 함수 연산을 위한 유니버셜 함수
함수 | 설명 |
sin(x, /[, out, where, casting, order, ...]) | Trigonometric sine, element-wise. |
cos(x, /[, out, where, casting, order, ...]) | Cosine element-wise. |
tan(x, /[, out, where, casting, order, ...]) | Compute tangent element-wise. |
arcsin(x, /[, out, where, casting, order, ...]) | Inverse sine, element-wise. |
arccos(x, /[, out, where, casting, order, ...]) | Trigonometric inverse cosine, element-wise. |
arctan(x, /[, out, where, casting, order, ...]) | Trigonometric inverse tangent, element-wise. |
arctan2(x1, x2, /[, out, where, casting, ...]) | Element-wise arc tangent of x1/x2 choosing the quadrant correctly. |
hypot(x1, x2, /[, out, where, casting, ...]) | Given the "legs" of a right triangle, return its hypotenuse. |
sinh(x, /[, out, where, casting, order, ...]) | Hyperbolic sine, element-wise. |
cosh(x, /[, out, where, casting, order, ...]) | Hyperbolic cosine, element-wise. |
tanh(x, /[, out, where, casting, order, ...]) | Compute hyperbolic tangent element-wise. |
arcsinh(x, /[, out, where, casting, order, ...]) | Inverse hyperbolic sine element-wise. |
arccosh(x, /[, out, where, casting, order, ...]) | Inverse hyperbolic cosine, element-wise. |
arctanh(x, /[, out, where, casting, order, ...]) | Inverse hyperbolic tangent element-wise. |
degrees(x, /[, out, where, casting, order, ...]) | Convert angles from radians to degrees. |
radians(x, /[, out, where, casting, order, ...]) | Convert angles from degrees to radians. |
deg2rad(x, /[, out, where, casting, order, ...]) | Convert angles from degrees to radians. |
rad2deg(x, /[, out, where, casting, order, ...]) | Convert angles from radians to degrees. |
- numpy.sin() 함수 사용 예
>>> np.sin(np.pi/2)
1.0
>>> np.sin(np.deg2rad(90))
1.0
>>> np.sin(np.array((0., 30., 45., 60., 90.)) * np.pi/180.)
array([0. , 0.5 , 0.70710678, 0.8660254 , 1. ])
- matplotlib.pyplot 모듈을 사용해 sin() 함수 그래프 그리기
import matplotlib.pyplot as plt
arr = np.linspace(-np.pi, np.pi, 201)
plt.plot(arr, np.sin(arr))
plt.xlabel('Angle [rad]')
plt.ylabel('sin(x)')
plt.axis('tight')
plt.show()
비트 단위 연산을 위한 유니버셜 함수
함수 | 설명 |
bitwise_and(x1, x2, /[, out, where, ...]) | Compute the bit-wise AND of two arrays element-wise. |
bitwise_or(x1, x2, /[, out, where, casting, ...]) | Compute the bit-wise OR of two arrays element-wise. |
bitwise_xor(x1, x2, /[, out, where, ...]) | Compute the bit-wise XOR of two arrays element-wise. |
invert(x, /[, out, where, casting, order, ...]) | Compute bit-wise inversion, or bit-wise NOT, element-wise. |
left_shift(x1, x2, /[, out, where, casting, ...]) | Shift the bits of an integer to the left. |
right_shift(x1, x2, /[, out, where, ...]) | Shift the bits of an integer to the right. |
- 사용 예
>>> np.bitwise_and(13, 17)
1
>>> np.binary_repr(12)
'1100'
>>> np.bitwise_and([14, 3], 13)
array([12, 1], dtype=int32)
비교(Comparison) 연산을 위한 유니버셜 함수
함수 | 설명 |
greater(x1, x2, /[, out, where, casting, ...]) | Return the truth value of (x1 > x2) element-wise. |
greater_equal(x1, x2, /[, out, where, ...]) | Return the truth value of (x1 >= x2) element-wise. |
less(x1, x2, /[, out, where, casting, ...]) | Return the truth value of (x1 < x2) element-wise. |
less_equal(x1, x2, /[, out, where, casting, ...]) | Return the truth value of (x1 <= x2) element-wise. |
not_equal(x1, x2, /[, out, where, casting, ...]) | Return (x1 != x2) element-wise. |
equal(x1, x2, /[, out, where, casting, ...]) | Return (x1 == x2) element-wise. |
logical_and(x1, x2, /[, out, where, ...]) | Compute the truth value of x1 AND x2 element-wise. |
logical_or(x1, x2, /[, out, where, casting, ...]) | Compute the truth value of x1 OR x2 element-wise. |
logical_xor(x1, x2, /[, out, where, ...]) | Compute the truth value of x1 XOR x2, element-wise. |
logical_not(x, /[, out, where, casting, ...]) | Compute the truth value of NOT x element-wise. |
maximum(x1, x2, /[, out, where, casting, ...]) | Element-wise maximum of array elements. |
minimum(x1, x2, /[, out, where, casting, ...]) | Element-wise minimum of array elements. |
fmax(x1, x2, /[, out, where, casting, ...]) | Element-wise maximum of array elements. |
fmin(x1, x2, /[, out, where, casting, ...]) | Element-wise minimum of array elements. |
플로팅(Floating) 연산을 위한 유니버셜 함수
함수 | 설명 |
isfinite(x, /[, out, where, casting, order, ...]) | Test element-wise for finiteness (not infinity and not Not a Number). |
isinf(x, /[, out, where, casting, order, ...]) | Test element-wise for positive or negative infinity. |
isnan(x, /[, out, where, casting, order, ...]) | Test element-wise for NaN and return result as a boolean array. |
isnat(x, /[, out, where, casting, order, ...]) | Test element-wise for NaT (not a time) and return result as a boolean array. |
fabs(x, /[, out, where, casting, order, ...]) | Compute the absolute values element-wise. |
signbit(x, /[, out, where, casting, order, ...]) | Returns element-wise True where signbit is set (less than zero). |
copysign(x1, x2, /[, out, where, casting, ...]) | Change the sign of x1 to that of x2, element-wise. |
nextafter(x1, x2, /[, out, where, casting, ...]) | Return the next floating-point value after x1 towards x2, element-wise. |
spacing(x, /[, out, where, casting, order, ...]) | Return the distance between x and the nearest adjacent number. |
modf(x[, out1, out2], / [[, out, where, ...]) | Return the fractional and integral parts of an array, element-wise. |
ldexp(x1, x2, /[, out, where, casting, ...]) | Returns x1 * 2**x2, element-wise. |
frexp(x[, out1, out2], / [[, out, where, ...]) | Decompose the elements of x into mantissa and twos exponent. |
fmod(x1, x2, /[, out, where, casting, ...]) | Returns the element-wise remainder of division. |
floor(x, /[, out, where, casting, order, ...]) | Return the floor of the input, element-wise. |
ceil(x, /[, out, where, casting, order, ...]) | Return the ceiling of the input, element-wise. |
trunc(x, /[, out, where, casting, order, ...]) | Return the truncated value of the input, element-wise. |
728x90
그리드형(광고전용)
'In-depth Study > NumPy' 카테고리의 다른 글
[NumPy] 넘파이 적용 (0) | 2022.04.14 |
---|---|
[NumPy] 배열 객체 관리와 연산 (0) | 2022.04.13 |
[NumPy] 넘파이 배열 (0) | 2022.04.13 |
[NumPy] 넘파이(NumPy) 개요 (0) | 2022.04.13 |