listname.count(v)
n, x = map(int, input().split())
- input(): 사용자로부터 입력을 받는 내장 함수입니다.
- .split(): 문자열을 특정 구분자를 기준으로 분리하여 리스트로 반환하는 문자열 메서드입니다.
이 두 동작이 함께 사용되면, 사용자로부터 입력을 받은 문자열을 공백이나 다른 구분자를 기준으로 분리하여 리스트로 만듭니다. 아래는 예제 코드입니다:
예를 들어, 사용자가 "Hello World"를 입력하면, result_list는 ['Hello', 'World']가 됩니다. 따라서, 여기서의 .은 문자열 메서드인 split()을 호출하기 위해 사용되는 문법적 표기법입니다.

split() 앞에 점(.)을 사용하는 것은 객체 지향 프로그래밍의 개념과 관련이 있습니다. 파이썬에서 거의 모든 것은 객체로 취급되며, 객체는 속성(attribute)과 메서드(method)를 가질 수 있습니다.
input() 함수는 문자열을 반환하며, 문자열은 문자열 관련 작업을 수행할 수 있는 다양한 메서드를 가지고 있습니다. split()은 문자열 메서드 중 하나이며, 문자열을 분리하여 리스트로 반환하는 역할을 합니다.
따라서, input() 함수로 반환된 문자열 객체에 대해 split() 메서드를 호출하려면 점(.)을 사용하여 객체의 메서드에 접근하는 것입니다. 이는 객체 지향 프로그래밍에서 메서드를 호출하는 표준적인 방식입니다.
간단히 말하면, input() 함수가 반환하는 문자열 객체의 split() 메서드를 호출하는 것이며, 이를 통해 문자열을 분리한 결과를 얻을 수 있습니다
Numpy 배열, 배열 생성 함수
1. Numpy
- 과학계산을 위한 라이브러리로 다차원 배열을 처리하는데 필요한 여러 기능을 제공
- Numpy를 사용하기 위해 import 함
import numpy as np
2. Numpy 배열
- Numpy에서 배열은 동일한 타입의 값들을 가짐
- rank: 배열의 차원
- shape: 각 차원의 크기를 tuple로 표시한 것
- Numpy에서 배열의 타입은 ndarray
3. Numpy 배열 생성
1) 파이썬의 리스트를 사용하는 방법
- array()함수의 인자로 리스트를 넣어 생성
[1 2 3 4] (4,)
[[1 2 3] [4 5 6]] (2, 3) 1
b = np.array([[1,2,3],[4,5,6]]) print(b) print(b.shape) b[0,0]
list1 = [1,2,3,4] a = np.array(list1) print(a) print(a.shape)
2) Numpy에서 제공하는 함수를 사용하는 방법
- zeros(): 배열에 모두 0을 집어 넣음
array([[0., 0.], [0., 0.]])
numpy.ndarray
type(aa)
aa = np.zeros((2,2)) aa
- ones(): 배열에 모두 1을 집어 넣음
array([[1., 1., 1.], [1., 1., 1.]])
aa = np.ones((2,3)) aa
- full(): 배열에 사용자가 지정한 값을 넣음
array([[10, 10, 10], [10, 10, 10]])
aa=np.full((2,3), 10) aa
- eye(): 대각선으로는 1이고 나머지는 0인 2차원 배열을 생성
array([[1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])
aa=np.eye(3) aa
- reshape(): 다차원으로 변형하는 함수
array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15], [16, 17, 18, 19]])
array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]])
aa=np.array(range(15)).reshape((3,5)) aa
aa=np.array(range(20)).reshape((5,4)) #range(n): 0~n-1까지의 숫자를 생성하는 함수 aa
출처: https://eunguru.tistory.com/208 [오늘도 난, 하하하:티스토리]
1. np.delete(arr, obj, axis=None)
이 함수는 생각보다 직관적인 함수입니다. 일단 "delete"는 삭제한다는 의미를 가지고 있습니다. 즉, 이 함수는 요소를 삭제하는 함수일 거 같습니다. 그리고 arr은 삭제할 배열, obj는 몇 번째를 삭제할 것인지, axis는 어느 축에서 삭제할 것인지입니다. 간단한 예제를 보도록 하겠습니다.
arr = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])
# array([[ 1, 2, 3, 4],
# [ 5, 6, 7, 8],
# [ 9, 10, 11, 12]])
np.delete(arr, 1, 0)
# array([[ 1, 2, 3, 4],
# [ 9, 10, 11, 12]])
np.delete(arr, 1, 1)
# array([[ 1, 3, 4],
# [ 5, 7, 8],
# [ 9, 11, 12]])
첫번째 delete 함수의 결과는 기존 배열에서 두번째 행을 제거하였습니다. 그리고 두번째 delete 함수의 결과는 기존 배열에서 두번째 열을 제거하였습니다. 즉, axis=0이면 행을 제거하고, axis=1이면 열을 제거하는 것입니다. 만약, axis를 지정해주지 않으면 아래와 같은 결과를 얻을 수 있습니다.
np.delete(arr, 1)
# array([ 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12])
결과를 보면 2차원 배열이 flatten되고 2번째 요소가 삭제된 것을 볼 수 있습니다. 이때, obj 인자에는 정수값이 들어갈 수도 있지만 배열이 들어갈 수도 있습니다. 이는 넘파이 객체를 인덱싱할 때 배열을 이용해서 인덱싱하는 것과 동일한 방법입니다.
np.delete(arr, [1,2], axis=0)
# array([[1, 2, 3, 4]])
np.delete(arr, [1,3], axis=1)
# array([[ 1, 3],
# [ 5, 7],
# [ 9, 11]])
np.delete(arr, [1,3], axis=None)
# array([ 1, 3, 5, 6, 7, 8, 9, 10, 11, 12])
첫번째 결과는 두번째, 세번째 행이 삭제되었습니다. 두번째 결과는 두번째, 네번째 열이 삭제되었습니다. 마지막으로 axis를 지정해주지 않으면 먼저 arr을 flatten하게 쭉 편 뒤 두번째, 네번째 인덱스에 해당하는 값이 삭제되었습니다.
2. np.insert(arr, obj, values, axis=None)
이번에는 insert라는 함수입니다. 이름에서도 느껴지시는 것처럼 값을 추가하는 함수입니다. 그래서 delete 함수와는 달리 어떤 값을 넣어줄지 결정해주는 values라는 인자가 추가된 것을 볼 수 있습니다. 이번에도 간단한 코드를 통해 이해해보도록 하겠습니다.
a = np.array([[1, 1], [2, 2], [3, 3]])
# array([[1, 1],
# [2, 2],
# [3, 3]])
np.insert(a, 1, 5)
# array([1, 5, 1, 2, 2, 3, 3])
np.insert(a, 1, 5, axis=0)
# array([[1, 1],
# [5, 5],
# [2, 2],
# [3, 3]])
np.insert(a, 1, 5, axis=1)
# array([[1, 5, 1],
# [2, 5, 2],
# [3, 5, 3]])
위의 결과부터 천천히 확인해보도록 하겠습니다. axis를 정해주지 않게 되면 delete 함수와 마찬가지로 a 배열을 flatten한 뒤 1번 인덱스(obj=1)에 값 5(values=5)를 삽입하여 얻은 결과를 볼 수 있습니다. 그 다음은 axis=0으로 지정하여 1번 인덱스(obj=1)의 행에 값 5(values=5)를 행 방향으로 삽입한 것을 볼 수 있습니다. 마지막 결과는 axis=1로 지정하여 1번 인덱스(obj=1)의 열에 값 5(values=5)를 열 방향으로 삽입한 것을 볼 수 있습니다!! 이와 같이 values를 단순히 스칼라 값으로 넣어주면 동일한 값으로 채우게 됩니다. 만약 서로 다른 값으로 채우고 싶다면 values를 삽입하려는 axis의 shape에 맞춰서 삽입할 배열을 넣어주면 됩니다.
np.insert(a, 1, [1, 2, 3], axis=1)
# array([[1, 1, 1],
# [2, 2, 2],
# [3, 3, 3]])
np.insert(a, 1, [1, 2, 3], axis=0)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-31-d9fc527df690> in <module>
----> 1 np.insert(a, 1, [1, 2, 3], axis=0)
<__array_function__ internals> in insert(*args, **kwargs)
~/anaconda3/lib/python3.7/site-packages/numpy/lib/function_base.py in insert(arr, obj, values, axis)
4593 new[tuple(slobj)] = arr[tuple(slobj)]
4594 slobj[axis] = slice(index, index+numnew)
-> 4595 new[tuple(slobj)] = values
4596 slobj[axis] = slice(index+numnew, None)
4597 slobj2 = [slice(None)] * ndim
ValueError: could not broadcast input array from shape (1,3) into shape (1,2)
만약, shape이 맞춰지지 않으면 아래의 오류를 얻을 수 있습니다. a 배열의 shape은 (2, 3)이기 때문에 axis=0 방향으로 삽입하기 위해서는 axis=0 방향의 shape은 2가 되어야합니다. 하지만 [1, 2, 3]은 shape이 3이기 때문에 브로드캐스팅 불가하다는 오류가 발생하는 것이죠. 이를 고치기 위해서는 아래와 같이 [1, 2, 3]이 아닌 [1, 2]로 넣어주면 됩니다.
np.insert(a, 1, [1, 2], axis=0)
# array([[1, 1],
# [1, 2],
# [2, 2],
# [3, 3]])
또한 delete와 마찬가지로 obj에 배열을 넣어 obj 배열의 인덱스에 맞게 값을 삽입해줍니다.
np.insert(a, [0, 3], [10, 20], axis=0)
# array([[10, 20],
# [ 1, 1],
# [ 2, 2],
# [ 3, 3],
# [10, 20]])
axis=0 방향으로 삽입하면 저희가 원하는 결과대로 0번째 행, 4번째 행에 각각 [10, 20]이 삽입되었습니다. 이번에는 axis=1 방향으로 삽입해보도록 하겠습니다.
np.insert(a, [0, 1, 2], [10, 20, 30], axis=1)
# array([[10, 1, 20, 1, 30],
# [10, 2, 20, 2, 30],
# [10, 3, 20, 3, 30]])
이 경우에는 저희가 원하는 결과가 나오지 않았습니다. 저희가 원하는 결과는 0번째 열, 1번째 열, 2번째 열에 각각 열 배열 [10, 20, 30]을 넣어주고 싶은 데 0번째 열에는 10만, 1번째 열에는 20만, 2번째 열에는 30만 들어갔습니다. 이러한 결과를 얻는 이유는 [10, 20, 30]이 열배열가 아닌 행배열로 인식되기 때문입니다. 따라서 이 문제를 해결하기 위해서는 [10, 20, 30]을 열배열로 변환해주면 됩니다. 그러므로 [[10], [20], [30]]으로 넘겨주면 저희가 원하는 결과를 얻을 수 있습니다.
np.insert(a, [0, 1, 2], [[10], [20], [30]], axis=1)
# array([[10, 1, 10, 1, 10],
# [20, 2, 20, 2, 20],
# [30, 3, 30, 3, 30]])
3. np.append(arr, values, axis=None)
이번에는 insert와 유사하게 배열을 삽입해주는 함수입니다. 혹시 파이썬에서 list의 삽입함수인 insert 함수와 append 함수를 기억하시나요? 그 두개의 차이와 동일합니다. insert 함수는 특정 인덱스에 원하는 배열을 삽입할 수 있습니다. append 함수는 항상 마지막 인덱스에 배열을 추가해줍니다. 그래서, insert 함수와는 다르게 obj 인자가 없는 것을 볼 수 있습니다. 이때, append 함수의 큰 특징은 axis를 명시하면 values의 차원의 수와 arr의 차원의 수가 동일해야합니다. 예를 들어서 arr의 차원의 수는 2인데, values의 차원의 수가 1이면 오류가 발생하게 됩니다. 따라서, 아래와 같이 차원을 맞추어줘야 오류없이 잘 실행됩니다.
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# array([[1, 2, 3],
# [4, 5, 6],
# [7, 8, 9]])
np.append(a, [10, 20, 30])
# array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30])
np.append(a, [[10, 20, 30]], axis=0)
# array([[ 1, 2, 3],
# [ 4, 5, 6],
# [ 7, 8, 9],
# [10, 20, 30]])
np.append(a, [[10], [20], [30]], axis=1)
# array([[ 1, 2, 3, 10],
# [ 4, 5, 6, 20],
# [ 7, 8, 9, 30]])
append 함수도 마찬가지로 axis를 정해주지 않으면 a 배열을 flatten 한 뒤에 마지막 부분에 [10, 20, 30]을 추가하고 있습니다. 이때는 axis를 명시하지 않았기 때문에 a와 [10, 20, 30]의 차원 수가 다르더라도 오류가 발생하지 않습니다. 하지만 아래의 2개의 append 함수에서는 axis를 명시했기 때문에 a와 차원의 수를 맞춰주기 위해서 강제로 2차원으로 만들어주는 것을 볼 수 있습니다. 만약, 차원의 수를 맞추어주지 않으면 아래와 같은 오류가 발생하게 됩니다.
np.append(a, [10, 20, 30], axis=0)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-66-4d3f9599c377> in <module>
----> 1 np.append(a, [10, 20, 30], axis=0)
<__array_function__ internals> in append(*args, **kwargs)
~/anaconda3/lib/python3.7/site-packages/numpy/lib/function_base.py in append(arr, values, axis)
4691 values = ravel(values)
4692 axis = arr.ndim-1
-> 4693 return concatenate((arr, values), axis=axis)
4694
4695
<__array_function__ internals> in concatenate(*args, **kwargs)
ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 2 dimension(s) and the array at index 1 has 1 dimension(s)
4. np.trim_zeros(filt, trim='fb')
다음 함수는 조금 결이 다른 함수입니다. 가끔 배열 중에 앞뒤에 필요없는 0이 있는 것을 많이 보신분들도 있습니다. 이 trim_zeros 함수는 넘파이 배열의 앞부분, 뒷부분에 해당하는 0들을 제거해주는 함수입니다. trim은 3가지 옵션이 존재합니다. 'f'로 지정하면 front, 앞부분의 0만 제거하게 됩니다. 'b'로 지정하면 back, 뒷부분의 0만 제거하게 됩니다. 'fb'는 디폴트 값으로 지정하면 front, back, 앞, 뒤의 0을 모두 제거하게 됩니다. 넘파이 배열의 앞뒷부분이 아닌 중간에 다른 값들 사이에 섞여있는 0값은 제거되지 않습니다. 이 함수는 매우 쉽기 때문에 간단한 예제 코드만 보고 넘어가도록 하겠습니다.
a = np.array((0, 0, 0, 1, 2, 3, 0, 2, 1, 0, 0, 0))
np.trim_zeros(a, trim='f')
# array([1, 2, 3, 0, 2, 1, 0, 0, 0])
np.trim_zeros(a, trim='b')
# array([0, 0, 0, 1, 2, 3, 0, 2, 1])
np.trim_zeros(a, trim='fb')
# array([1, 2, 3, 0, 2, 1])
5.np.unique(ar, return_index=False, return_inverse=False, return_counts=False, axis=None)
개인적으로 넘파이 라이브러리에서 중요하고 유용한 함수를 선택한다면 저는 개인적으로 unique 함수를 선택할 거 같습니다. 이 함수는 여러 개의 값들이 존재하는 넘파이 배열에서 어떤 값으로만 구성되어있는 지, 최초로 등장하는 값의 인덱스(return_index), 입력 배열을 재구축할 수 있는 인덱스 배열(return_inverse), 각 값이 넘파이 패열에서 등장하는 횟수(return_counts)를 아래와 같이 반환 할 수 있습니다.
a = np.array([1, 2, 2, 3, 3, 3])
# array([1, 2, 2, 3, 3, 3])
np.unique(a)
# array([1, 2, 3])
np.unique(a, return_index=True)
# (array([1, 2, 3]), array([0, 1, 3]))
np.unique(a, return_index=True, return_inverse=True)
# (array([1, 2, 3]), array([0, 1, 3]), array([0, 1, 1, 2, 2, 2]))
np.unique(a, return_index=True, return_inverse=True, return_counts=True)
# (array([1, 2, 3]),
# array([0, 1, 3]),
# array([0, 1, 1, 2, 2, 2]),
# array([1, 2, 3]))
물론 원한다면 특정 axis에 해당하는 행이나 열을 통째로 고유한 값을 확인해 볼 수 있습니다.
a = np.array([[1, 0, 0], [1, 0, 0], [2, 3, 4]])
# array([[1, 0, 0],
# [1, 0, 0],
# [2, 3, 4]])
np.unique(a, axis=0)
# array([[1, 0, 0],
# [2, 3, 4]])
np.unique(a, axis=1)
# array([[0, 0, 1],
# [0, 0, 1],
# [3, 4, 2]])
'python > 문법' 카테고리의 다른 글
[python] [문법] 문자열과 list 차이 (0) | 2024.01.18 |
---|---|
[python] [문법] [행렬] [[list] 정리 (0) | 2024.01.18 |
[python] [문법] [print] (0) | 2024.01.17 |
[python] [문법] [map] (0) | 2024.01.16 |
python 에서 .의 의미 (0) | 2024.01.03 |