Skip to content Skip to sidebar Skip to footer

Numpy Delete List Element From List Of Lists

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,r

Solution 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]]

Solution 2:

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]])

Solution 3:

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.


Post a Comment for "Numpy Delete List Element From List Of Lists"