簡體   English   中英

有什么辦法可以刪除python中numpy數組“就地”的特定元素:

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM