[英]Is there any way to delete the specific elements of an numpy array “In-place” in python:
當調用“ np.delete()”時,我不希望為減小尺寸的數組定義一個新變量。 我想對原始的numpy數組執行刪除。 任何想法?
>>> arr = np.array([[1,2], [5,6], [9,10]])
>>> arr
array([[ 1, 2],
[ 5, 6],
[ 9, 10]])
>>> np.delete(arr, 1, 0)
array([[ 1, 2],
[ 9, 10]])
>>> arr
array([[ 1, 2],
[ 5, 6],
[ 9, 10]])
but I want:
>>> arr
array([[ 1, 2],
[ 9, 10]])
NumPy數組是固定大小的,因此不能有np.delete
的就地版本。 任何此類函數都必須更改數組的大小。
您可以獲得的最接近的結果是重新分配arr
變量:
arr = numpy.delete(arr, 1, 0)
delete
調用不會修改原始數組,而是將其復制並在刪除完成后返回副本。
>>> arr1 = np.array([[1,2], [5,6], [9,10]])
>>> arr2 = np.delete(arr, 1, 0)
>>> arr1
array([[ 1, 2],
[ 5, 6],
[ 9, 10]])
>>> arr2
array([[ 1, 2],
[ 9, 10]])
如果是性能問題,您可能要嘗試創建一個視圖*(而不是測試不 np.delete
而不是使用np.delete
。 您可以通過切片來做到這一點,它應該是就地操作:
import numpy as np
arr = np.array([[1, 2], [5, 6], [9, 10]])
arr = arr[(0, 2), :]
print(arr)
導致:
[[ 1 2]
[ 9 10]]
但是,這不會釋放排除行中占用的內存。 它可能會提高性能,但在內存方面,您可能會遇到相同或更嚴重的問題。 還應注意,據我所知,沒有通過排除索引的方法(例如arr[~1]
將非常有用),這必然會使您花費資源來建立索引數組。
對於大多數情況,我認為其他用戶給出的建議是:
arr = numpy.delete(arr, 1, 0)
, 是最好的。 在某些情況下,可能值得探索另一種選擇。
編輯: *這實際上是不正確的(感謝@ user2357112)。 花式索引不會創建視圖,而是返回一個副本,就像在文檔中可以看到的那樣(我在跳轉到結論之前應該檢查一下,對此感到抱歉):
Advanced indexing always returns a copy of the data (contrast with basic slicing that returns a view).
因此,我不確定花式索引建議是否值得作為實際建議,除非它相對於np.delete
方法有任何性能np.delete
(我將嘗試在機會出現時進行驗證, 請參閱EDIT2 )。
EDIT2:我執行了一個非常簡單的測試,以查看是否有使用反對派的華麗索引來刪除功能帶來的性能提升。 用過的timeit (實際上是我第一次使用,但似乎每個代碼段的執行次數為1 000 000,因此時間的最高數字):
import numpy as np
import timeit
def test1():
arr = np.array([[1, 2], [5, 6], [9, 10]])
arr = arr[(0, 2), :]
def test2():
arr = np.array([[1, 2], [5, 6], [9, 10]])
arr = np.delete(arr, 1, 0)
print("Equality test: ", test1() == test2())
print(timeit.timeit("test1()", setup="from __main__ import test1"))
print(timeit.timeit("test2()", setup="from __main__ import test2"))
結果如下:
Equality test: True
5.43569152576767
9.476918448174644
這代表了非常可觀的速度提升。 但是請注意,建立花式索引的順序將花費一些時間。 是否值得,一定取決於所要解決的問題。
您可以實現自己的delete
版本,該版本將數據元素復制到要刪除的元素之后,然后返回不包含最后一個元素(現已過時)的視圖:
import numpy as np
# in-place delete
def np_delete(arr, obj, axis=None):
# this is a only simplified example
assert (isinstance(obj, int))
assert (axis is None)
for i in range(obj + 1, arr.size):
arr[i - 1] = arr[i]
return arr[:-1]
Test = 10 * np.arange(10)
print(Test)
deleteIndex = 5
print(np.delete(Test, deleteIndex))
print(np_delete(Test, deleteIndex))
您的代碼沒有錯。 您只需要override
變量
arr = np.array([[1,2], [5,6], [9,10]])
arr = np.delete(arr, 1, 0)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.