Tôi có một numpy
mảng 2D . Có cách nào để tạo chế độ xem trên đó sẽ bao gồm các k
hà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:
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 y
sẽ được phản ánh trong x
và 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 += 10
sẽ sửa đổi mảng tại chỗ, trong khi x = x + 10
sẽ 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.0
sẽ x
tự độ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 x
là một mảng số nguyên, thay vào đó, nó sẽ 10.0
bị é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 out
tham 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 x
tạ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.0
là một 64 bit float trên một hệ thống little-endian sẽ được 4607182418800017408
xem 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.
b
là một lượt xem a
, thì b.base is a
sẽ là True
. Bản sao (của bất kỳ mảng) sẽ luôn luôn cóarr_copy.base is None
x[np.array([1, 1, 3, 1])] += 1
sửa đổix
. Bây giờ có nó!