Xem vào một mảng numpy?


90

Tôi có một numpymảng 2D . Có cách nào để tạo chế độ xem trên đó sẽ bao gồm các khàng đầu tiên và tất cả các cột?

Vấn đề là tránh sao chép dữ liệu bên dưới (mảng quá lớn nên việc sao chép từng phần là không khả thi.)

Câu trả lời:


226

Chắc chắn, chỉ cần lập chỉ mục nó như bình thường. Ví dụ: y = x[:k, :] Điều này sẽ trả lại một khung nhìn vào mảng ban đầu. Không có dữ liệu nào sẽ được sao chép và bất kỳ cập nhật nào được thực hiện ysẽ được phản ánh trong xvà ngược lại.


Biên tập:

Tôi thường làm việc với các mảng 3D> 10GB của uint8, vì vậy tôi lo lắng về điều này rất nhiều ... Numpy có thể quản lý bộ nhớ rất hiệu quả nếu bạn lưu ý một số điều. Dưới đây là một số mẹo để tránh tạo bản sao của mảng trong bộ nhớ:

Sử dụng +=, -=, *=, vv để tránh đưa ra một bản sao của mảng. Ví dụ: x += 10sẽ sửa đổi mảng tại chỗ, trong khi x = x + 10sẽ tạo một bản sao và sửa đổi nó. (ngoài ra, hãy xem sốxpr )

Nếu bạn muốn tạo một bản sao với x = x + 10, hãy lưu ý rằng điều đó x = x + 10.0sẽ xtự động được đưa vào một mảng dấu phẩy động, nếu nó chưa có. Tuy nhiên, x += 10.0ở đâu xlà một mảng số nguyên, thay vào đó, nó sẽ 10.0bị ép xuống thành một số nguyên có cùng độ chính xác với mảng.

Ngoài ra, nhiều hàm numpy nhận một outtham số, vì vậy bạn có thể làm những việc như np.abs(x, x)lấy giá trị tuyệt đối xtại chỗ.


Là lần chỉnh sửa thứ hai, đây là một số mẹo khác về lượt xem so với bản sao với mảng không có hạt:

Không giống như danh sách python, y = x[:] không trả về một bản sao, nó trả về một dạng xem. Nếu bạn muốn một bản sao (dĩ nhiên, sẽ tăng gấp đôi dung lượng bộ nhớ bạn đang sử dụng)y = x.copy()

Bạn sẽ thường nghe nói về "lập chỉ mục ưa thích" của các mảng numpy. Sử dụng một danh sách (hoặc mảng số nguyên) làm chỉ mục là "lập chỉ mục ưa thích". Nó có thể rất hữu ích, nhưng sao chép dữ liệu.

Ví dụ về điều này: y = x[[0, 1, 2], :]trả về một bản sao, trong khiy = x[:3,:] sẽ trả về một chế độ xem.

Ngay cả lập chỉ mục thực sự điên rồ như x[4:100:5, :-10:-1, None] là "bình thường" và sẽ trả về một chế độ xem, vì vậy đừng ngại sử dụng tất cả các loại thủ thuật cắt trên các mảng lớn.

x.astype(<dtype>)sẽ trả về một bản sao của dữ liệu dưới dạng kiểu mới, trong khi x.view(<dtype>)sẽ trả về một dạng xem.

Hãy cẩn thận với điều này, tuy nhiên ... Nó cực kỳ mạnh mẽ và hữu ích, nhưng bạn cần hiểu cách dữ liệu cơ bản được lưu trữ trong bộ nhớ. Nếu bạn có một mảng float và xem chúng dưới dạng int, (hoặc ngược lại) numpy sẽ diễn giải các bit bên dưới của mảng là int.

Ví dụ, điều này có nghĩa 1.0là một 64 bit float trên một hệ thống little-endian sẽ được 4607182418800017408xem là một int 64 bit và một mảng [ 0, 0, 0, 0, 0, 0, 240, 63]nếu được xem như một uint8. Tuy nhiên, điều này thực sự tốt khi bạn cần thực hiện xáo trộn bit trên một số mảng lớn ... Bạn có quyền kiểm soát mức thấp đối với cách bộ đệm bộ nhớ được diễn giải.


Cảm ơn vì những lời khuyên rất hay! Tôi đang đọc hướng dẫn sử dụng Numpy và bối rối tại sao lại x[np.array([1, 1, 3, 1])] += 1sửa đổi x. Bây giờ có nó!
tnq177

mẹo hay! Tôi có câu hỏi khác. Làm thế nào để chứng minh rằng numpy không kích hoạt một bản sao mà chỉ là một lượt xem? id của python () dường như không có khả năng này.
wuhaochi

3
@wuhaochi Nếu blà một lượt xem a, thì b.base is asẽ là True. Bản sao (của bất kỳ mảng) sẽ luôn luôn cóarr_copy.base is None
Jürg Merlin Spaak
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.