繁体   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