0

I have an array of numpy arrays:

a = [[1, 2, 3, 4], [1, 2, 3, 5], [2, 5, 4, 3], [5, 2, 3, 1]]

I need to find and remove a particular list from a:

rem = [1,2,3,5]

numpy.delete(a,rem) does not return the correct results. I need to be able to return:

[[1, 2, 3, 4], [2, 5, 4, 3], [5, 2, 3, 1]]

is this possible with numpy?

2
  • So, remove all rows that are same as rem? Commented Oct 31, 2016 at 18:28
  • You really need to be clear whether you have lists or arrays, and whether you have multidimensional arrays or arrays of arrays. Commented Oct 31, 2016 at 19:47

3 Answers 3

1

A list comprehension can achieve this.

rem = [1,2,3,5]
a = [[1, 2, 3, 4], [1, 2, 3, 5], [2, 5, 4, 3], [5, 2, 3, 1]]
a = [x for x in a if x != rem]

outputs

[[1, 2, 3, 4], [2, 5, 4, 3], [5, 2, 3, 1]]
Sign up to request clarification or add additional context in comments.

Comments

1

Numpy arrays do not support random deletion by element. Similar to strings in Python, you need to generate a new array to delete a single or multiple sub elements.

Given:

>>> a
array([[1, 2, 3, 4],
       [1, 2, 3, 5],
       [2, 5, 4, 3],
       [5, 2, 3, 1]])
>>> rem
array([1, 2, 3, 5])

You can get each matching sub array and create a new array from that:

>>> a=np.array([sa for sa in a if not np.all(sa==rem)])
>>> a
array([[1, 2, 3, 4],
       [2, 5, 4, 3],
       [5, 2, 3, 1]])

To use np.delete, you would use an index and not a match, so:

>>> a
array([[1, 2, 3, 4],
       [1, 2, 3, 5],
       [2, 5, 4, 3],
       [5, 2, 3, 1]])
>>> np.delete(a, 1, 0)   # delete element 1, axis 0
array([[1, 2, 3, 4],
       [2, 5, 4, 3],
       [5, 2, 3, 1]])

But you can't loop over the array and delete elements...

You can pass multiple elements to np.delete however and you just need to match sub elements:

>>> a
array([[1, 2, 3, 5],
       [1, 2, 3, 5],
       [2, 5, 4, 3],
       [5, 2, 3, 1]])
>>> np.delete(a, [i for i, sa in enumerate(a) if np.all(sa==rem)], 0)
array([[2, 5, 4, 3],
       [5, 2, 3, 1]])

And given that same a, you can have an all numpy solution by using np.where:

>>> np.delete(a, np.where((a == rem).all(axis=1)), 0)
array([[2, 5, 4, 3],
       [5, 2, 3, 1]])

Comments

1

Did you try list remove?

In [84]: a = [[1, 2, 3, 4], [1, 2, 3, 5], [2, 5, 4, 3], [5, 2, 3, 1]]
In [85]: a
Out[85]: [[1, 2, 3, 4], [1, 2, 3, 5], [2, 5, 4, 3], [5, 2, 3, 1]]
In [86]: rem = [1,2,3,5]
In [87]: a.remove(rem)
In [88]: a
Out[88]: [[1, 2, 3, 4], [2, 5, 4, 3], [5, 2, 3, 1]]

remove matches on value.

np.delete works with an index, not value. Also it returns a copy; it does not act in place. And the result is an array, not a nested list (np.delete converts the input to an array before operating on it).

In [92]: a = [[1, 2, 3, 4], [1, 2, 3, 5], [2, 5, 4, 3], [5, 2, 3, 1]]
In [93]: a1=np.delete(a,1, axis=0)
In [94]: a1
Out[94]: 
array([[1, 2, 3, 4],
       [2, 5, 4, 3],
       [5, 2, 3, 1]])

This is more like list pop:

In [96]: a = [[1, 2, 3, 4], [1, 2, 3, 5], [2, 5, 4, 3], [5, 2, 3, 1]]
In [97]: a.pop(1)
Out[97]: [1, 2, 3, 5]
In [98]: a
Out[98]: [[1, 2, 3, 4], [2, 5, 4, 3], [5, 2, 3, 1]]

To delete by value you need first find the index of the desired row. With integer arrays that's not too hard. With floats it is trickier.

=========

But you don't need to use delete to do this in numpy; boolean indexing works:

In [119]: a = [[1, 2, 3, 4], [1, 2, 3, 5], [2, 5, 4, 3], [5, 2, 3, 1]]
In [120]: A = np.array(a)     # got to work with array, not list
In [121]: rem=np.array([1,2,3,5])

Simple comparison; rem is broadcasted to match rows

In [122]: A==rem
Out[122]: 
array([[ True,  True,  True, False],
       [ True,  True,  True,  True],
       [False, False, False, False],
       [False,  True,  True, False]], dtype=bool)

find the row where all elements match - this is the one we want to remove

In [123]: (A==rem).all(axis=1)
Out[123]: array([False,  True, False, False], dtype=bool)

Just not it, and use it to index A:

In [124]: A[~(A==rem).all(axis=1),:]
Out[124]: 
array([[1, 2, 3, 4],
       [2, 5, 4, 3],
       [5, 2, 3, 1]])

(the original A is not changed).

np.where can be used to convert the boolean (or its inverse) to indicies. Sometimes that's handy, but usually it isn't required.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.