numpy 배열로 보시겠습니까?


90

2D numpy배열이 있습니다. 첫 번째 k행과 모든 열을 포함하는 뷰를 만드는 방법이 있습니까?

요점은 기본 데이터를 복사하지 않는 것입니다 (배열이 너무 커서 부분 복사가 불가능 함).

답변:


228

물론입니다. 평소처럼 색인을 생성하면됩니다. 예 : y = x[:k, :] 이것은 원래 배열로보기를 반환합니다. 데이터는 복사되지 않으며에 대한 모든 업데이트는 y반영 x되며 그 반대의 경우도 마찬가지입니다.


편집하다:

나는 일반적으로 uint8의> 10GB 3D 배열로 작업하므로 이것에 대해 많이 걱정합니다. Numpy는 몇 가지 사항을 염두에두면 메모리 관리에 매우 효율적일 수 있습니다. 다음은 메모리에 배열 복사를 방지하는 몇 가지 팁입니다.

사용 +=, -=, *=, 등이 배열의 복사를 방지 할 수 있습니다. 예 x += 10를 들어 배열을 제자리에서 x = x + 10수정하고 복사본을 만들고 수정합니다. (또한 numexpr 살펴 보십시오 )

당신이 복사본을 만들고 싶어 경우 x = x + 10, 그 인식 x = x + 10.0의 원인이됩니다 x자동으로 이미 아니었다면, 부동 소수점 배열에 최대 캐스트. 그러나 x += 10.0, 여기서 x정수 배열이며, 원인 것 10.0대신으로 배열과 같은 정밀도 int로 다운 캐스트.

또한 많은 numpy 함수가 out매개 변수 np.abs(x, x)를 취하므로 x제자리에서 절대 값을 취하는 것과 같은 작업을 수행 할 수 있습니다 .


두 번째 편집으로, 여기에 몇 가지 더 팁의 전망사본 NumPy와 배열과를 :

파이썬 목록과 달리 y = x[:]복사본을 반환하지 않고보기를 반환합니다. 복사본을 원하면 (물론 사용중인 메모리 양의 두 배가 됨) 다음을 사용하십시오.y = x.copy()

numpy 배열의 "멋진 인덱싱"에 대해 자주 듣게 될 것입니다. 목록 (또는 정수 배열)을 인덱스로 사용하는 것은 "멋진 인덱싱"입니다. 매우 유용 할 수 있지만 데이터를 복사합니다.

예를 들어 : y = x[[0, 1, 2], :]복사본 y = x[:3,:]을 반환하고 뷰를 반환합니다.

정말 미친 인덱싱조차도 x[4:100:5, :-10:-1, None]"일반"인덱싱이며 뷰를 반환하므로 큰 배열에서 모든 종류의 슬라이싱 트릭을 사용하는 것을 두려워하지 마십시오.

x.astype(<dtype>)데이터 사본을 새 유형으로 x.view(<dtype>)반환하고 뷰를 반환합니다.

그러나 이것에주의하십시오. 매우 강력하고 유용하지만 기본 데이터가 메모리에 저장되는 방식을 이해해야합니다. float 배열이 있고이를 int로 보는 경우 (또는 그 반대의 경우) numpy는 배열 의 기본 비트 를 int로 해석합니다 .

예를 들어, 1.0리틀 엔디안 시스템에서 64 비트 float 4607182418800017408는 64 비트 int로 볼 때, 배열은 [ 0, 0, 0, 0, 0, 0, 240, 63]uint8로 볼 때입니다. 이것은 큰 배열에서 일종의 비트 트위들 링을해야 할 때 정말 좋습니다. 메모리 버퍼가 해석되는 방식에 대해 낮은 수준의 제어가 가능합니다.


아주 좋은 팁에 감사드립니다! Numpy 사용자 가이드를 읽고 왜 x[np.array([1, 1, 3, 1])] += 1수정 했는지 혼란 스러웠습니다 x. 이제 알았습니다!
tnq177

좋은 팁! 다른 질문이 있습니다. numpy가 복사가 아니라 뷰를 트리거한다는 것을 증명하는 방법은 무엇입니까? 파이썬의 id ()는 이것을 할 수없는 것 같습니다.
wuhaochi

3
@wuhaochi 경우 b의 도면이다 a, 다음 b.base is a될 것입니다 True. (모든 배열의) 사본은 항상있을 것이다arr_copy.base is None
Jürg 멀린 Spaak
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.