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