Переглянути масив numpy?


90

У мене 2D- numpyмасив. Чи є спосіб створити вид на нього, який би включав перші kрядки та всі стовпці?

Сенс у тому, щоб уникнути копіювання базових даних (масив настільки великий, що часткове копіювання неможливе.)

Відповіді:


226

Звичайно, просто проіндексуйте, як зазвичай. Наприклад, y = x[:k, :] це поверне перегляд вихідного масиву. Жодні дані не будуть скопійовані, а будь-які оновлення, що були зроблені, yбудуть відображені в xі навпаки.


Редагувати:

Я зазвичай працюю з> 10 Гб тривимірних масивів uint8, тому я дуже про це переживаю ... 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)прийняти абсолютне значення xin-place.


Як друге редагування, ось ще кілька порад щодо переглядів та копій із масивами numpy:

На відміну від списків python, y = x[:]не повертає копію, він повертає подання. Якщо вам потрібна копія (яка, звичайно, подвоїть обсяг використовуваної вами пам’яті)y = x.copy()

Ви часто будете чути про "вигадливу індексацію" масивів numpy. Використання списку (або цілочисельного масиву) як індексу - це «вигадне індексування». Це може бути дуже корисно, але копіює дані.

Як приклад цього: y = x[[0, 1, 2], :]повертає копію, whiley = x[:3,:] повертає подання.

Навіть по-справжньому божевільне індексування подобається x[4:100:5, :-10:-1, None] "звичайна" індексація, поверне подання, однак, не бійтеся використовувати всілякі фокуси нарізки на великих масивах.

x.astype(<dtype>)поверне копію даних як новий тип, тоді як x.view(<dtype>)поверне подання.

Однак будьте обережні з цим ... Це надзвичайно потужне та корисне, але ви повинні розуміти, як основні дані зберігаються в пам'яті. Якщо у вас є масив плаваючих значень, і ви розглядаєте їх як ints, (або навпаки) numpy буде інтерпретувати базові біти масиву як ints.

Наприклад, це означає, що 1.0як 64-бітний плаваючий пристрій з малою ендіанською системою буде 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 python () здається нездатним до цього.
wuhaochi

3
@wuhaochi Якщо bце погляд a, тоді b.base is aбуде True. Копія (будь-якого масиву) завжди будеarr_copy.base is None
Юрг Мерлін Спаак
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.