2021. 8. 18. 00:21ㆍpython/pandas, numpy
indexing
python list의 indexing과 slicing과 상당히 유사
indexig은 차원이 준다[n] 왜냐하면 안에 있는걸 뽑기때문
slicing은 차원을 유지[n:n] (원본유지)원래 형태를 유지하기때문에
import numpy as np
# arr = np.arange(10,20,1)
# for item in arr:
# print(item)
enumerate: 열거하다 / 위치와 값을 찍는다
# for idx,item in enumerate(arr):
# print(idx, item)
0 10
1 11
2 12
3 13
# slicing
arr = np.arange(0,5,1)
print(arr)
tmp = arr[0:3]
print(tmp)
arr[0] = 100
print(arr)
print(tmp)
# numpy의 ndarray에 대해서 slicing을 하면 view가 만들어져요!!
import numpy as np
# arr = np.arange(0,5,1)
# print(arr) [0, 1, 2, 3, 4]
# print(arr[0:3]) [0, 1, 2]
# print(arr[0:-1]) [0, 1, 2, 3]
# print(arr[0::2]) [0, 2, 4]
arr = np.array([[1,2,3],
[4,5,6],
[7,8,9],
[10,11,12]])
print(arr)
[ , ] 기준으로 행과 열이 변경
print(arr[1,2]) #6 2차원 ndarray의 indexing(1행2열)
print(arr[2,:]) #[7, 8, 9] 1차원의 ndarray가 결과로 나와요(view)
print(arr[1:3,:]) # [[4, 5, 6] [7, 8, 9]] 결과값이 2차원이므로 주의
Boolean Indexing
# Boolean Indexing은 배열의 각 요소의 선택여부를 True,False로 구성된 (python의 bool)
# Boolean Mask를 이용하여 지정하는 방식으로
# Boolean Mask안에서 True로 지정된 요소만 indexing하는 방식.
import numpy as np
arr = np.arange(0,5,1)
print(arr)
# print(arr[3]) # 3 기본 indexing
# [0 1 2 3 4 5 6 7 8 9]
# b_mask = [True, False, False, False, False, True, False, False, True, True]
# print(arr[b_mask]) # [0 5 8 9]
사칙연산
print(arr + 1) - +1은 shape이 없다 이를 '스칼라 '
사칙연산 특징
# 만약 ndarray에 사칙연산이 수행되려면 shape이 같아야해요!
# 만약 연산을 할때 shape이 다르면 shape을 자동으로 맞출려고 해요! '브로드캐스팅' : 흩뿌리고 퍼뜨리고 전파
# arr = np.arange(0,5,1)
# arr2 = np.arange(10,15,1)
# print(arr + arr2) #[10, 12, 14, 16, 18]
브로드캐스팅
# arr = np.arange(0,5,1)
# arr2 = np.arange(10,13,1)
# print(arr + 1)각 값에 1씩 더한다
# [0 1 2 3 4]
# [1 1 1 1 1]
위 상황에서 print(arr + arr2)
arr2가 3개면 +2를 못하므로 불가능
만약 arr1이 6개면 arr2값 * 2로 가능하다
# arr % 2 # [0 1 0 1 0]
# [0 1 2 3 4]
# [2 2 2 2 2]
# arr % 2 == 0
# [0 1 2 3 4]
# [2 2 2 2 2]
# [0 0 0 0 0]
# [True, False, True, False, True]
# arr[arr % 2 == 0]
arr이 가진거중에 []를 계산하여 짝수만 나온다 / (데이터가 많은상태로 if 문이라면 하루종일 걸린다) # array([0, 2, 4])
문제 .import numpy as np
# 1부터 100까지 3의 배수의 개수는??arr = np.arange(1,101,1)
print(len(arr[arr % 3 == 0])) # 33
Fancy Indexing (원하다.., 하고싶다)
fancy indexing은 차원을 유지, 원하는 것만 뽑아내기때문
# ndarray에 index 배열(list, ndarray)을 전달해서 indexing하는 방식
# 리스트형태로 만들어서 해당 값 위치에서 값을 가져온다
arr = np.arange(10,15,1)
print(arr)
print(arr[1]) # 숫자 indexing(기본)
print(arr[[0, 2, 3]])
#[10 12 13]
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
import numpy as np
arr = np.arange(0,12,1).reshape(3,4).copy()
print(arr)
[[0 1 2 3]
[4 5 6 7]
[8 9 10 11]]
# indexing (기본)
# print(arr[2,1]) #9
(slicing과 indexing 차원 주의 !!)
# print(arr[1:2,2]) # [6]
# print(arr[1:2,2:3]) # [[6]]
fancy indexing
# print(arr[[0,2],2]) # [2 10]
# print(arr[[0,2],2:3]) # [[2]
# [10]]
# print(arr[[0,2],[0,2]]) # 원하는 결과가 나오지 않아요!
둘다 fancy indexing을 내부구조상 사용할수 없다!!
np.ix_([0,2][0,2]) 를 이용해 사용 가능
# print(arr[np.ix_([0,2],[0,2])]) # 이렇게 사용해야 해요! == print(arr[[0,2]][:,[0,2]])
# [[0 2]
# [8 10]]
사칙연산 , 행렬곱
np.matmul(행렬곱) 연산에서는 broadcasting이 발생하지 않아요!
# broadcasting
import numpy as np
arr1 = np.array([[1,2,3], [4,5,6]]) # 2 x 3 ndarray
arr2 = np.arange(10,16,1).reshape(2,3).copy()
print(arr1)
print(arr2)
# 같은 shape일 경우 연산수행이 가능
print(arr1 + arr2)
# print(arr1 > arr2) booliean mask로 나온다
[[False False False]
[False False False]]
# a = [1, 2, 3]
# b = [4, 5, 6]
# print(a + b) # python의 list인 경우 concatenate [1, 2, 3, 4, 5, 6]
# 행렬곱연산 ( matrix multiplication : 매트릭스 곱하기)
# 앞쪽행렬의 열의 개수와 뒤쪽 행렬의 행의 개수가 같아야 행렬곱 연산이 성립!
# a = np.array([[1,2], [3,4], [5,6]]) # 3 x 2
# b = np.array([[1,2,3], [4,5,6]]) # 2 x 3
# print(np.matmul(a,b)) numpy 곱셈시 사용
broadcasting '브로드캐스팅' : 흩뿌리고 퍼뜨리고 전파
자동으로 늘어난다
import numpy as np
arr1 = np.array([[1,2,3],
[4,5,6]]) # 2 x 3 2차원 ndarray
arr2 = np.array([1,2,3]) # 1차원 ndarray
# arr1과 arr2에 대해서 사칙연산을 수행하고 싶어요!
# shape이 같아야 연산이 수행될 수 있어요!
print(arr1 + arr2) # OK
arr2가 3개면 +2를 못하므로 불가능
만약 arr1이 6개면 arr2값 * 2로 가능하다
#array([[2, 4, 6], [5, 7, 9]])
print(arr1 * 3) # scaler(단일숫자)는 broadcasting이 쉬워요!
########## np.matmul(행렬곱) 연산에서는 broadcasting이 발생하지 않아요!
반복문을 사용하고 싶어요! (nditer)
# 1차원 데이터면 그냥 지금까지 했더것처럼 for나 while을 사용하면 되요!
# 2차원 데이터면 for문이 2번
# 3차원 데이터면 for문이 3번
###################################
# ndarray에 대해서 반복처리를 할 때는 iterator를 이용하는걸 권장!
# iternext() 함수와 finished라는 속성을 이용해서 ndarray의 모든 요소를 반복적으로 aceess할 수 있어요!
import numpy as np
# 1차원 ndarray
# arr = np.array([1, 2, 3, 4, 5])
# 일반적인 for문을 이용한 ndarray access ( win!! )
# for tmp in arr:
# print(tmp, end=' ')
# iterator를 이용한 1차원 ndarray access
# 지정된 flag의 형태를 가지는 iterator를 추출 ( 어려워요!! )
# it = np.nditer(arr, flags=['c_index']) # 이렇게 만든 iterator로 부터 우리가 index를 추출할 수 있는데
# # 이 index의 형태가 c언어의 index형태와 같다!
# # 0, 1, 2, 3, 4, 5, arr[0]
# while not it.finished:
# idx = it.index
# print(arr[idx], end=' ')
# it.iternext()
# 2차원 ndarray
arr = np.array([1,2,3],[4,5,6]) # shape => (2,3)
# for tmp1 in range(arr.shape[0]):
# for tmp2 in range(arr.shape[1]):
# print(arr[tmp1,tmp2], end=' ')
it = np.nditer(arr, flags=['multi_index']) # 이렇게 만든 iterator로 부터 우리가 index를 추출할 수 있는데
# 이 index의 형태가 c언어의 index형태가 아니예요!
# tuple형태로 나와요!
while not it.finished:
idx = it.multi_index # (1,0)
print(arr[idx], end=' ')
it.iternext()
ndarray의 다양한 집계함수
import numpy as np
arr = np.arange(1,7,1).reshape(2,3).copy()
# print(arr)
[[1 2 3][4 5 6]]
# # print(arr.sum())
# print(np.sum(arr)) # 합
# print(np.mean(arr)) # 평균
# print(np.max(arr)) # 최대값
# print(np.min(arr)) # 최소값
# print(np.argmax(arr)) # 최대값을 찾아서 그 최대값의 index / 2차원이라도 1차원으로 만들어 몇번째인지
# print(np.std(arr)) # 표준편차
# numpy의 모든 집계함수는 axis(축)를 기준으로 계산.
# 위의 예처럼 axis를 명시하지 않으면 axis는 None을 설정되요!
# 이런 경우 집계함수의 대상은 전체 ndarray로 간주
# 1차원 ndarray인 경우
# arr = np.array([1, 2, 3, 4, 5])
# print(arr.sum(axis=0)) # 1차원인 경우 축의 번호는 0이고 이때 0의 의미는 열 (열 방향)
# 2차원 ndarray인 경우
# arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# print(arr)
# # print(arr.sum(axis=1)) # 2차원인 경우 축의 번호는 0과 1을 쓸 수 있고 0이 행, 1이 열
# print(arr.argmax(axis=1)) # [2 2 2]
# np.random.seed(1)
# arr = np.random.randint(0,5,(2,2,3))
# print(arr)
[[[3 4 0]
[ 1 3 0]
[[0 1 4]
[4 1 2]]]
# print(arr.sum(axis=0)) #
[[3 5 4]]
[5 4 2]]
# 간단한 문제를 하나 풀어보아요!
# 랜덤으로 정수형 난수를 생성할꺼예요!
# 만들어지는 정수형 난수의 범위는 1(포함) ~ 10(포함) 총 12개 생성해서
# 3행 4열 2차원 ndarray로 만들꺼예요!
# ndarray안에 있는 난수 중 5 이상인 숫자들의 합을 구해서 출력하세요!
np.random.seed(1)
arr = np.random.randint(1, 11, (3,4))
print(arr[arr >= 5].sum())
'python > pandas, numpy' 카테고리의 다른 글
dataframe으로 json이용 (0) | 2021.08.19 |
---|---|
pandas 기초 (0) | 2021.08.19 |
numpy 3일차 (0) | 2021.08.18 |
numpy 정리 (0) | 2021.08.18 |
numpy 1일차 (0) | 2021.08.17 |