답변:
한 번에 둘 이상의 열에 액세스하려면 다음을 수행하십시오.
>>> test = np.arange(9).reshape((3,3))
>>> test
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
>>> test[:,[0,2]]
array([[0, 2],
[3, 5],
[6, 8]])
test[:,[0,2]]
예를 들어 test[:, [0,2]] = something
테스트를 수정하고 다른 배열을 만들지 않는 데이터에 액세스하기 만하면 됩니다. 그러나 copy_test = test[:, [0,2]]
실제로 당신이 말하는대로 사본을 만듭니다.
test[:,[0,2]]
동안 왜 데이터에 액세스 test[:, [0, 2]][:, [0, 1]]
합니까? 같은 일을 다시하는 것은 다른 결과를 가져 오는 것은 매우 직관적이지 않은 것 같습니다.
>>> test[:,0]
array([1, 3, 5])
이 명령은 행 벡터를 제공합니다. 루프 벡터를 반복하고 싶다면 괜찮습니다. 그러나 차원이 3xN 인 다른 배열로 hstack하고 싶다면
ValueError: all the input arrays must have same number of dimensions
동안
>>> test[:,[0]]
array([[1],
[3],
[5]])
연결 또는 hstack 작업을 수행 할 수 있도록 열 벡터를 제공합니다.
예 :
>>> np.hstack((test, test[:,[0]]))
array([[1, 2, 1],
[3, 4, 3],
[5, 6, 5]])
행을 바꾸고 반환 할 수도 있습니다.
In [4]: test.T[0]
Out[4]: array([1, 3, 5])
여러 개의 열을 얻으려면 다음을 수행하십시오.
> test[:,[0,2]]
당신은 열 0과 2를 얻을 것이다
질문에 대한 답변이 있지만 뉘앙스에 대해 언급하겠습니다.
배열의 첫 번째 열에 관심이 있다고 가정 해 봅시다.
arr = numpy.array([[1, 2],
[3, 4],
[5, 6]])
다른 답변에서 이미 알고 있듯이 "행 벡터"(array of shape (3,)
) 형식으로 얻으려면 슬라이싱을 사용하십시오.
arr_c1_ref = arr[:, 1] # creates a reference to the 1st column of the arr
arr_c1_copy = arr[:, 1].copy() # creates a copy of the 1st column of the arr
배열이 다른 배열의 뷰인지 또는 사본인지 확인하려면 다음을 수행하십시오.
arr_c1_ref.base is arr # True
arr_c1_copy.base is arr # False
ndarray.base를 참조하십시오 .
둘 사이의 명백한 차이 (수정 arr_c1_ref
은에 영향을 미침 arr
) 외에도 각각을 통과하는 바이트 단계 수는 다릅니다.
arr_c1_ref.strides[0] # 8 bytes
arr_c1_copy.strides[0] # 4 bytes
보폭을 참조하십시오 . 이것이 왜 중요한가? : A
대신에 매우 큰 배열이 있다고 상상해보십시오 arr
.
A = np.random.randint(2, size=(10000,10000), dtype='int32')
A_c1_ref = A[:, 1]
A_c1_copy = A[:, 1].copy()
첫 번째 열의 모든 요소, 즉 A_c1_ref.sum()
또는 의 합을 계산하려고합니다 A_c1_copy.sum()
. 복사 된 버전을 사용하는 것이 훨씬 빠릅니다.
%timeit A_c1_ref.sum() # ~248 µs
%timeit A_c1_copy.sum() # ~12.8 µs
이것은 앞에서 언급 한 보폭이 다르기 때문입니다.
A_c1_ref.strides[0] # 40000 bytes
A_c1_copy.strides[0] # 4 bytes
열 복사본을 사용하는 것이 더 나은 것처럼 보이지만 복사본을 만드는 데 시간이 걸리고 더 많은 메모리를 사용하는 이유는 항상 사실이 아닙니다 (이 경우을 만드는 데 약 200µs가 걸렸습니다 A_c1_copy
). 그러나 처음에 사본이 필요하거나 배열의 특정 열에 대해 여러 가지 다른 작업을 수행해야하고 속도를 위해 메모리를 희생하면 사본을 만드는 것이 좋습니다.
주로 열을 다루는 데 관심이있는 경우 행 주요 ( 'C') 순서 대신 열-주요 ( 'F') 순서로 배열을 만드는 것이 좋습니다. )을 누른 다음 열을 복사하지 않고 이전과 같이 슬라이싱을 수행하십시오.
A = np.asfortranarray(A) # or np.array(A, order='F')
A_c1_ref = A[:, 1]
A_c1_ref.strides[0] # 4 bytes
%timeit A_c1_ref.sum() # ~12.6 µs vs ~248 µs
이제 열보기에서 합계 작업 (또는 다른 작업)을 수행하는 것이 훨씬 빠릅니다.
마지막으로 배열을 바꾸고 행 슬라이싱을 사용하는 것은 원래 배열의 모양과 보폭을 바꾸는 것만으로 변환이 이루어 지므로 원래 배열의 열 슬라이싱을 사용하는 것과 같습니다.
A.T[1,:].strides[0] # 40000