Julien
Julien

Reputation: 35

numpy delete an array value (logical zero)

The short story is: I am trying to delete a precise point in an array, by using a logical zero or any other way.

I am starting with some points' coordinates which define a wing. With them, I am trying to form a nice polygon with no crossing lines. This is done by starting at point one (any one point), and then filling in the next point as the point closest to the first point.

The coordinates are loaded as xEdge and yEdge. First thing I do is create a copy of them with only 0 in it as follow. xEdgeOrdered and yEdgeOrdered will be filled with the polygon points. I will also create one with only ones which will be used to check which values are already taken by the polygon.

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

We then start our polygon with the y-maximum for instance, and here starts the problem.

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

In the last line, when I state notUsed[startIndex] = 0, what I'm really trying to do is replace the "USED" value as a logical 0 -- the "false" in matlab. The aim is that this value is not reachable any more, basically deleted from the array.

I have tried to mask it (see below), but I find it doesn't work perfectly in the script's next step.

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

The next step is a loop which finds the next closest points. I will first try to describe what I am trying to do in words and I will attach my code after (which does not work yet...).

Starting from the initial point 1, I need to find the next closest point using vector length. I will try all remaining points. To know which are the remaining points, I give my function the argument "notUsed", which remember is an array with "1" if the point is not used, or 0 if it is used (by 0 we would like to mean "false" but we haven't found how yet). What I have done is make a carbon copy of xEdge as xEdgewhile, set the value we just used to 0, then ask that values = 0 should be masked

Once the minimum value is found, the index position is recorded. Using it, we can fill this new point in xEdgeOrderedn and continue the loop starting from this new point. However, before that, we need to delete the index we just used so that it is not accessible anymore. If we were in matlab, we would do notUsed(index) = false; - the question is How can I do this in Python?

This is the code I came up with:

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)

For reference, I can also give you the matlab code if it helps. Long story short, I am trying to delete a precise point in an array, by using a logical zero or any other way.

Upvotes: 0

Views: 1026

Answers (2)

philE
philE

Reputation: 1703

Not sure I exactly understand the context, but in reference to your "long story short," there are a couple ways to go about deleting a specific point in an array. If you want to delete the element corresponding to a specific value, you use logicals to select all array elements except for those that have that value. For example,

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

Note that this will only work the way you seem to want it to work if val occurs only once in your array. If you have an index of the element that you want to remove, use numpy.delete() as referenced here

numpy.delete(a, index)

Or, if you don't want to delete it, but just want to turn it into another value (eg. 0),

a[index] = 0

EDIT

Then again, if you don't want to mess with the original array at all but just want to take specific elements out of consideration, you can use an index array and delete elements of that accordingly. For example,

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

Note the output from this sequence when index is, say, 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])

Using this method, you can leave your array fixed but dynamically modify your consideration set.

Upvotes: 1

Julien
Julien

Reputation: 35

Than you for your answer.

The issue came from the fact that Numpy arrays' dimensions are fixed, thus it is impossible to delete any of their item. The solution can be to replace the value with another one that cannot be reached by your function, or to use lists instead of arrays.

Upvotes: 0

Related Questions