如何向numpy的2维数组中添加或删除特定元素?

5

给定以下numpy数组:

arr = np.array([
    [1,2,3],
    [4,5,6],
    [7,8,9]
])

删除并返回:

arr = np.array([
    [1,2,3],
    [4,6],
    [7,8,9]
])

我想从这个数组中删除5或仅删除arr[1][2]。当我使用del arr[i][j]时,它会抛出以下错误:ValueError: cannot delete array elements,而且对于这种情况,numpy文档对我来说不够清晰。
类似地,在同一个数组的一些行中如何添加元素?
具体来说,当我用opencv读取图像时,我遇到了这个错误。 rgb_image = cv2.imread("image.png") del操作给我带来了上面的错误,并且我无法通过np.delete(...)解决它。

这不是一个二维数组,我不想完全删除一列或一行。只有特定的元素应该被删除。 - DragonKnight
@unlut 这是一个二维数组。我更新了问题。 - DragonKnight
2
你会为每个数组执行多个操作吗? - Atle Kristiansen
这个删除操作在二维数组中没有意义,你可以使用列表的列表来进行删除,而不是数组。 - hpaulj
1
请注意,由于每行元素的数量不是恒定的,因此结果不会是一个数组,因此您可以使用列表来处理它。 - yatu
显示剩余10条评论
3个回答

3

一个numpy数组(ndarray)是引用:

ndarray是通常是固定大小的多维容器,包含相同类型和大小的项。

如果您想使用ndarray数据结构(及其所有优化),则不能有不同长度的行。

一个可能的解决方法是使用列表数组。

>>> arr=np.array([
    [1,2,3],
    [4,5,6],
    [7,8,9],
    []
])

(注意空行以逃避ndarray数据类型)

所以您可以从其中一个列表中删除元素

>>> arr
array([list([1, 2, 3]), list([4, 5, 6]), list([7, 8, 9]), list([])],
      dtype=object)
>>> arr[1]=np.delete(arr[1], [1], axis=0)
>>> arr
array([list([1, 2, 3]), array([4, 6]), list([7, 8, 9]), list([])],
      dtype=object)

一般情况下,对于对象数据类型的数组进行操作比等价嵌套列表要慢。而且 np.delete 比列表的 del 操作要慢得多。np.delete 会将其输入转换为数组(如果尚未是数组),并返回一个新数组。 - hpaulj

2
我认为一种方法是将np.array转换为列表,再将其重新转换为np.array,就像这样:

我认为一种方法是将np.array转换为列表,再将其重新转换为np.array,就像这样:

arr = arr.tolist()
arr[1].pop(1)
arr = np.array(arr)

编辑: 看起来是正确的,numpy的方法:

最初的回答

np.delete(arr, [4, 4])
np.split(arr, [3, 5, 9])

编辑2:看起来并不会节省时间,但你可以尝试以下方法:

arr =  np.empty(3, dtype=np.object)
arr[:] = [1,2,3], [4,5,6], [7,8,9]
arr[1].remove(5)

这很昂贵。这是对图像的操作,想象一下这必须重复宽度高度100次。 - DragonKnight
我明白了,也许你可以使用 np.delete 就像这样:new = np.delete(arr, [4, 4]),然后以某种方式拆分成列表元素。 - K.Maj
我使用它是因为在使用np.delete之后,我得到了一个扁平化的一维数组。只是为了再次获得2D表示。 - K.Maj
1
还有,正如我在第一行中提到的arr[:] = [1,2,3], [4,5,6], [7,8,9],只是用于初始化。如果你只读取图像数组,应该在预处理之前这样做...所以在你的情况下,应该是 arr[:] = im.read(path) #或类似的语句 - K.Maj
1
arr.tolist()非常快。 - hpaulj
显示剩余7条评论

1
首先使用new_list = list(old_array)函数将数组转换为列表。(这将创建一个数组列表)
现在,您可以执行所有列表操作,如pop,filter等,以删除不需要的元素。
最后,当您拥有筛选过的列表时,请使用new_array = np.array(new_list)将其转换回数组。(这个新数组将保留旧数组的维度)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接