У мене 2D- numpy
масив. Чи є спосіб створити вид на нього, який би включав перші k
рядки та всі стовпці?
Сенс у тому, щоб уникнути копіювання базових даних (масив настільки великий, що часткове копіювання неможливе.)
Відповіді:
Звичайно, просто проіндексуйте, як зазвичай. Наприклад, 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)
прийняти абсолютне значення x
in-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. Це справді приємно, коли вам потрібно виконати певне перетворення бітів на великих масивах, однак ... Ви маєте низький рівень контролю над інтерпретацією буфера пам'яті.
b
це погляд a
, тоді b.base is a
буде True
. Копія (будь-якого масиву) завжди будеarr_copy.base is None
x[np.array([1, 1, 3, 1])] += 1
модифікованийx
. Тепер зрозуміло!