numpy 删除数组中的值(逻辑零)

0 投票
2 回答
1017 浏览
提问于 2025-04-18 19:35

简单来说:我想在一个数组中删除一个特定的点,可以用逻辑零或者其他方法。

我开始时有一些点的坐标,这些点定义了一个翼的形状。接着,我想用这些点形成一个没有交叉线的漂亮多边形。这个过程是从第一个点开始(随便选一个点),然后填入下一个点,选择离第一个点最近的那个。

这些坐标被加载为xEdge和yEdge。首先,我会创建一个只包含0的副本,像这样。xEdgeOrdered和yEdgeOrdered将用来存放多边形的点。我还会创建一个只包含1的数组,用来检查哪些值已经被多边形占用了。

xEdgeOrdered = np.zeros_like(xEdge)
yEdgeOrdered = np.zeros_like(xEdge)
notUsed = np.ones_like(xEdge)

然后我们从y值最大的点开始构建多边形,这里就出现了问题。

startIndex = np.argmax(yEdge)
xEdgeOrdered[0] = xEdge[startIndex]
notUsed[startIndex] = 0 

在最后一行,当我写notUsed[startIndex] = 0时,我实际上是想把“已使用”的值替换成逻辑上的0——在matlab中是“false”。目的是让这个值不再可达,基本上就是从数组中删除。

我尝试过用掩码(见下文),但发现它在脚本的下一步中并不完全有效。

notUsed = np.ma.masked_where(notUsed == 0, notUsed)

下一步是一个循环,用来找到下一个最近的点。我会先用文字描述我想做的事情,然后附上我的代码(目前还不工作...)。

从初始点1开始,我需要使用向量长度找到下一个最近的点。我会尝试所有剩下的点。为了知道哪些是剩下的点,我给我的函数传入参数“notUsed”,这个数组中如果点没有被使用就为“1”,如果被使用则为0(我们想用0表示“false”,但还没有找到方法)。我所做的是把xEdge的副本复制为xEdgewhile,把刚刚使用的值设为0,然后要求值为0的点被掩盖

一旦找到最小值,就记录下它的位置。利用这个位置,我们可以把这个新点填入xEdgeOrdered中,然后从这个新点继续循环。但是,在那之前,我们需要删除刚刚使用的索引,以便它不再可访问。如果我们在matlab中,会写notUsed(index) = false;问题是我该如何在Python中做到这一点?

这是我想到的代码:

i, z, min = 1, 0, 'inf'
xEdgewhile = xEdge + []; yEdgewhile = yEdge + [];
while i < len(xEdge):
      i = i + 1
      notUsedIndices = indexVector  #This line might be useless
      while z < len(xEdge):
        distance = math.sqrt((xEdgewhile[z] - xEdgeOrdered[(i-1)])**2 + (yEdgewhile[z] - yEdgeOrdered[(i - 1)])**2 )
        if distance < min:
          min, distance_min, = distance, z
        z = z + 1
        print min
      xEdgeOrdered[i] = xEdge[distance_min]
      yEdgeOrdered[i] = yEdge[distance_min]
      xEdgewhile[distance_max], yEdgewhile[distance_min] = 0, 0
      xEdgewhile = np.ma.masked_where(xEdgewhile == 0, xEdgewhile)
      yEdgewhile = np.ma.masked_where(yEdgewhile == 0, yEdgewhile)

如果需要,我也可以给你matlab的代码,看看是否有帮助。总之,我想在一个数组中删除一个特定的点,可以用逻辑零或者其他方法。

2 个回答

0

谢谢你的回答。

问题的原因在于,Numpy数组的维度是固定的,所以你不能删除里面的任何一个元素。解决办法可以是用一个你函数无法访问的其他值来替换掉这个元素,或者干脆用列表来代替数组。

1

我不太确定我是否完全理解你的背景,不过关于你提到的“长话短说”,有几种方法可以删除数组中的特定点。如果你想删除一个特定值对应的元素,可以用逻辑方法选择所有数组元素,除了那个特定值的元素。比如:

import numpy as np
a = np.array([1, 2, 3, 4, 5])
val = 3
# If you want to delete the value
b = a[a != val]
# If you want the value to become something else (eg. 0)
a[a == val] = 0

需要注意的是,这种方法只有在你的数组中val只出现一次时,才会像你想的那样工作。如果你有想要删除的元素的索引,可以使用numpy.delete(),具体可以参考这里

numpy.delete(a, index)

或者,如果你不想删除它,而只是想把它变成另一个值(比如0),

a[index] = 0

编辑

再说,如果你根本不想动原始数组,只是想把特定元素排除在外,你可以使用索引数组,然后相应地删除那些元素。比如:

b = np.arange(len(a))
# Begin algorithm on a[b]
# Once an element is found in a and should no longer be considered...
b = np.delete(b, index)
# Repeat

注意当索引为2时,这个序列的输出结果

>>> b = np.arange(len(a))
>>> a[b]
array([1, 2, 3, 4, 5])
>>> b = np.delete(b, 2)
>>> a[b]
array([1, 2, 4, 5])

使用这种方法,你可以保持数组不变,但动态地修改你考虑的元素集合。

撰写回答