[python]_numpy_5

Hi K·2022년 10월 20일

numpy

목록 보기
4/4

배열 복사

arr.copy() / np.copy(arr)

  • 인덱싱, 슬라이싱을 통해 반환된 배열은 원본 배열에 대해 독립적인 새로운 객체가 아닌 원본 배열과 종속적인 객체
  • 원본과 독립적인 복사본인 배열을 생성 : arr.copy() / np.copy(arr)

(얕은복사) : a를 복사한 b는 a의 주소를 공유하기 때문에
b를 수정하면 a도 변경됨
(깊은복사) : a를 복사한 c는 독립적인 새로운 객체가 됨, c를 수정해도 a는 변경안됨

a = [1, 2, 3]
a2 = [1, 2, 3]

# 얕은복사
b = a
# 깊은복사 1 
c = a2[:]
print(b[0])
print(c[0])
print(a, a2)

b[0] = 10
c[0] = 10
print(a, a2) 
# b[0]을 바꿨는데 a[0]이 바뀜, c[0]은 바꿔도 a2[0]이 바뀌진 않음

# 0부터 3까지 범위로 1씩 증가하는 2 * 2 구조 배열 생성
arr1 = np.arange(0,4).reshape(2,2)
np_print(arr1)

# 깊은복사 2
arr2 = arr1.copy()
# 얕은복사
arr3 = arr1

arr2[0,0] = 100

print(arr2)
print(arr1)
print(arr3)

arr3[0,0] = 100
print(arr2)
print(arr1)
print(arr3)


배열 변환

1. 전치(Transpose)

  • 배열의 행/열 인덱스가 바뀌는 변환
  • 배열객체.T : 행/열 인덱스가 바뀐 새로운 배열을 반환하며 원본은 변경되지 않음

# 1이상 12이하의 값을 가지는 3 * 4구조의 배열 생성
arr1 = np.arange(1, 13).reshape(3, 4)
np_print(arr1)

print(arr1.T)
print(arr1)
# 원본이 변경되지 않기 때문에 따로 저장해야 한다

2. 배열 형태 변경

arr.ravel(), np.ravel(arr)

- 다차원 배열을 1차원 배열로 변환
- np.ravel() : 1차원으로 변환되는 결과는 원본 배열에 반영되지 않음
- arr.ravel() : 1차원으로 변환하는 배열의 요소가 변경되면 원본 배열에도 반영됨

arr.reshape(new_shape), np.reshape(arr, new_shape)

- 원본 배열 객체의 구조(shape)를 변경
- 변경하려는 구조의 전체 요소 개수와 원본 배열의 전체 요소 개수가 동일해야 함
- 변경하려는 구조의 튜플 중 하나의 원소는 -1로 대체할 수 있고 다른 하나의 원소를 기준으로 계산되어 사용됨
- reshape() 메서드가 반환하는 배열의 요소가 변경되면 원본 배열에도 반영됨
# 다차원 배열을 1차원 배열로 변환
arr2 = arr1.ravel()
print(arr1)
print(arr2)

np_print(arr2)

# 변환 후 값 수정, 원본과 비교
arr2[0] = 10

print(arr1)
print(arr2)

# arr1을 6 * 2로 바꾸되 하나의 축에 대해 -1을 사용해봅시다
arr3 = arr1.reshape(-1, 2)
arr3

# 변환 후 값 수정, 원본과 비교
arr3[0] = [100, 200]

arr1

3. 요소 변경, 추가, 삭제

1) 요소 변경

arr.resize(new_shape), np.resize(arr, new_shape)

- 배열 메서드를 사용하면 원본 변경, np 함수를 사용하면 새로운 배열 반환
- 배열의 구조(shape)를 변경하며 원본 배열의 요소 수와 동일하지 않아도 변경 가능
- 변경되는 배열의 요소 수가 동일할 경우 : reshape() 메서드와 동일한 결과
- 변경되는 배열의 요소 수가 더 많을 경우
    - np.resize(arr, new_shape) : 원본을 변경하지 않고, 모자란 부분을 기존 배열 값에서 복사해서 추가
    - arr.resize(new_shape) : 원본을 변경하고, 모자란 부분을 0으로 채움
    - 공통적으로 new_shape은 튜플로 추가
- 변경되는 배열의 요소 수가 더 작을 경우 : 마지막 남은 요소 삭제
# 1이상 10미만의 범위의 랜덤 정수값으로 3 * 5 구조를 가진 배열 생성
arr = np.random.randint(1, 10, (3, 5))
np_print(arr)

arr2 = np.random.randint(1, 10, (3, 5))
np_print(arr2)

arr.resize(new_shape)

# 변경되는 배열의 요소 수가 동일한 경우 : reshape()와 동일하게 동작함
arr.resize(5, 3)
arr.size

arr

np.resize(arr, new_shape)

# 변경 후 배열의 요소 갯수가 더 많은 경우
arr3 = np.resize(arr2, (6, 3))
np_print(arr3)

# refcheck = False인 경우만 크기가 다를 때 0으로 남는 자리를 채워줌
arr.resize((6, 3), refcheck=False)
np_print(arr)

# 변경되는 배열의 요소 수가 더 적은 경우 : 마지막 남은 요소를 삭제
# 크기가 원본과 resize를 이용했을 때 다르다면 refcheck=False를 반드시 넣는다
arr.resize((3,3), refcheck=False)
np_print(arr)

2) 요소 추가

np.append(arr, values, axis=None)

- arr 마지막에 values를 추가
- axis 지정하지 않는 경우(기본값) : 1차원 배열로 변형되어 결합
- axis = 0 : 행 방향으로 결합 (단, 열의 개수가 동일해야 함)
- axis = 1 : 열 방향으로 결합 (단, 행의 개수가 동일해야 함)
- 원본 배열들에 반영되지 않음
# 1이상 10미만의 범위에서 1씩 증가하는 숫자로 3 * 3 구조의 배열 a 생성
# 10이상 19미만의 범위에서 1씩 증가하는 숫자로 3 * 3 구조의 배열 b 생성

a = np.arange(1, 10).reshape(3, 3)
b = np.arange(10, 19).reshape(3, 3)
np_print(a)
np_print(b)

# 2개의 배열 결합
# axis를 지정하지 않는 경우 : np.append(arr1, arr2) => axis = None
# arr1, arr2 모두 1차원으로 변형해서 추가함
np.append(a, b)

# 2개의 배열 결합
# axis=0 : 행 단위 결합 : 열 개수는 3개로 동일
np.append(a,b, axis=0)

# 2개의 배열 결합
# axis=1 : 열 단위 결합 : 행 개수는 3개로 동일
np.append(a,b, axis=1)

# 열의 개수가 다른 배열과의 결합
c = np.arange(30, 45).reshape(3, 5)
np_print(c)

# a와 c를 결합해주세요
# 방향을 바꾸면 에러나는 것도 확인해주세요.
np.append(a, c, axis=0)

np.append(a, c, axis=1)

# 행 단위로 결합할 수 있는 구조로 변경(resize 활용)
c.resize((5, 3))
c

np.append(a, c, axis=0)

# 행 개수가 다른 배열과의 결합
d = np.arange(90, 102).reshape(4, 3)
np_print(d)

b

np.append(b, d, axis=0)

np.append(b, d.reshape(3,4), axis=1)

  • np.insert(arr, idx, values, axis=None)
    • 지정한 인덱스(idx)에 value를 추가
    • axis 지정하지 않는 경우(기본값) : 1차원 배열의 변형되고 해당 인덱스에 추가
    • axis = 0 : 행 방향으로 n번째 행에 추가
    • axis = 1 : 열 방향으로 n번째 열에 추가
    • 원본 배열에 반영되지 않음
# 1이상 10미만 범위에서 1씩 증가하는 숫자로 3 x 3 구조의 배열 생성
arr = np.arange(1, 10).reshape(3, 3)
np_print(arr)

# 원본 배열은 유지
arr

# aixs = 0 : 행 방향으로 index번째 행을 추가
# a배열의 1번 인덱스 행에 100을 추가 =>> 행의 요소 개수(열 개수)만큼 100이 추가됨
np.insert(arr, 1, 100, axis=0)

# aixs = 1 : 열 방향으로 index 번째 행을 추가
# a 배열의 2번 인덱스 열에 200추가
np.insert(arr,2, 200, axis=1)

# 요소마다 다른 값으로 행/열 추가하기
# 요소의 개수를 동일하게 작성 -> 축을 기준으로 요소 개수 결정 -> axis로 축 설정
np.insert(arr, 2, [10, 20, 30], axis=1)

3) 요소 삭제

np.delete(arr, idx, axis=None)

- 지정한 인덱스(idx)에 해당하는 요소를 삭제
- axis 지정하지 않는 경우(기본값) : 1차원 배열로 변형되어 해당 인덱스에 해당하는 요소를 삭제
- axis = 0 : 행 방향으로 n번째 행을 삭제
- axis = 1 : 열 방향으로 n번째 열을 삭제
- 원본 배열에 반영되지 않음
a

# a.reshape(9)
np.ravel(a)

# axis를 지정 안 하는 경우 : 1차원 배열로 변환 -> 지정한 index에 해당하는 요소를 삭제
# a배열에 대해 1번 인덱스 요소를 삭제
np.delete(a, 1)

# 원본 배열은 변경되지 않음
a

# a배열 세로축으로 0번째 삭제
np.delete(a, 0, axis=0)

# a배열 가로축으로 0번째 삭제
np.delete(a, 0, axis=1)

4) 배열 결합

np.concatenate((arr1, arr2, ...), axis=0)

- axis = 0(기본값) : 행 방향으로 두 배열 결합 (단, 열의 개수가 동일)
- axis = 1 : 열 방향으로 두 배열 결합 (단, 행의 개수가 동일)
- 원본 배열들은 변경되지 않음
# 1이상 7미만의 범위에서 1씩 증가하는 숫자로 2 x 3 구조의 배열 a 생성
# 7이상 13미만의 범위에서 1씩 증가하는 숫자로 2 x 3 구조의 배열 b 생성
# 13이상 23미만의 범위에서 1씩 증가하는 숫자로 2 x 5 구조의 배열 c 생성(열개수 다름)
# 23이상 38미만의 범위에서 1씩 증가하는 숫자로 5 x 3 구조읩 배열 d 생성(행개수 다름)
a = np.arange(1, 7).reshape(2, 3)
b = np.arange(7, 13).reshape(2, 3)
c = np.arange(13, 23).reshape(2, 5)
d = np.arange(23, 38).reshape(5, 3)

print(a)
print()
print(b)
print()
print(c)
print()
print(d)
print()

# axis = 0(기본값) : 행 방향으로 두 배열 결합
# np.append(a, b)
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
np.concatenate((a, b))

# aixs = 1 : 열 방향으로 두 배열 결합
np.concatenate((a,b), axis=1)

# 행 방향으로 결합 : 열 개수가 동일해야함
np.concatenate((a,c))

np.concatenate((a,c),axis=1)

# 열 방향으로 결합 : 행 개수 동일
np.concatenate((a,d),axis=1)

np.concatenate((a,d))

np.split(arr, indices_or_sections, axis=0)

- axis = 0(기본값) : 행 단위로 분리
- axis = 1 : 열 단위로 분리
- 원본 배열은 변경되지 않음
a = np.arange(1, 37).reshape(6, 6)
a

# 균등하지 않게 행 기준으로 분리
np.split(a, [1, 2, 3], axis=0)

# 균등하지 않게 행 기준으로 분리
# 리스트로 넘기면 위치를 지정합니다.
# 스칼라 값을 넘기면 균등하게 갯수를 맞춰서 쪼개줍니다.
# 스칼라값으로 처리시 반드시 나눈 갯수가 정수로 떨어져야 합니다.
np.split(a, 3, axis=0)

# 리스트 형태이기 때문에 인덱싱 가능
np.split(a, 3, axis=0)[0]

# 균등한 간격으로 열 기준으로 3개 분리
np.split(a, 3, axis=1)

profile
파이썬초짜의 기록

0개의 댓글