numpy 删除数组中的值(逻辑零)
简单来说:我想在一个数组中删除一个特定的点,可以用逻辑零或者其他方法。
我开始时有一些点的坐标,这些点定义了一个翼的形状。接着,我想用这些点形成一个没有交叉线的漂亮多边形。这个过程是从第一个点开始(随便选一个点),然后填入下一个点,选择离第一个点最近的那个。
这些坐标被加载为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 个回答
谢谢你的回答。
问题的原因在于,Numpy数组的维度是固定的,所以你不能删除里面的任何一个元素。解决办法可以是用一个你函数无法访问的其他值来替换掉这个元素,或者干脆用列表来代替数组。
我不太确定我是否完全理解你的背景,不过关于你提到的“长话短说”,有几种方法可以删除数组中的特定点。如果你想删除一个特定值对应的元素,可以用逻辑方法选择所有数组元素,除了那个特定值的元素。比如:
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])
使用这种方法,你可以保持数组不变,但动态地修改你考虑的元素集合。