How do you 'remove' a numpy array from a list of numpy arrays?

后端 未结 4 2023
北海茫月
北海茫月 2021-01-11 13:43

If I have a list of numpy arrays, then using remove method returns a value error.

For example:

import numpy as np

l = [np.array([1,1,1]),np.array([2         


        
4条回答
  •  佛祖请我去吃肉
    2021-01-11 14:08

    Use Base Functionalities from Python and Numpy

    You can run the following one-liner to get the result ...

    import numpy as np
    
    # Your inputs ...
    l = [np.array([1, 1, 1]), np.array([2, 2, 2]), np.array([3, 3, 3])]
    array_to_remove = np.array([2, 2, 2])
    
    # My result ...
    result = [a for a, skip in zip(l, [np.allclose(a, array_to_remove) for a in l]) if not skip]
    
    print(result)
    

    ... or copy paste the following in a script and experiment a bit.

    You need

    • numpy.allclose to compare numpy arrays up to floating point representation error
    • zip
    • list comprehension
    • the concept of a mask

    Note, ...

    • this solution returns a list without all occurencies of the array we searched for
    • the returned list has references to the np.ndarray instances also referred from the initial list. There are no copies!

    import numpy as np
    
    
    def remove(array, arrays):
        """
        Remove the `array` from the `list` of `arrays`
        Returns list with remaining arrays by keeping the order.
    
        :param array: `np.ndarray`
        :param arrays: `list:np.ndarray`
        :return: `list:np.ndarray`
        """
    
        assert isinstance(arrays, list), f'Expected a list, got {type(arrays)} instead'
        assert isinstance(array, np.ndarray), f'Expected a numpy.ndarray, got {type(array)} instead'
        for a in arrays:
            assert isinstance(a, np.ndarray), f'Expected a numpy.ndarray instances in arrays, found {type(a)} instead'
    
        # We use np.allclose for comparing arrays, this will work even if there are
        # floating point representation differences.
        # The idea is to create a boolean mask of the same lenght as the input arrays.
        # Then we loop over the arrays-elements and the mask-elements and skip the
        # flagged elements
        mask = [np.allclose(a, array) for a in arrays]
        return [a for a, skip in zip(arrays, mask) if not skip]
    
    
    if __name__ == '__main__':
    
        # Let's start with the following arrays as given in the question
        arrays = [np.array([1, 1, 1]), np.array([2, 2, 2]), np.array([3, 3, 3])]
        print(arrays)
    
        # And remove this array instance from it.
        # Note, this is a new instance, so the object id is
        # different. Structure and values coincide.
        _arrays = remove(np.array([2, 2, 2]), arrays)
    
        # Let's check the result
        print(_arrays)
    
        # Let's check, whether our edge case handling works.
        print(arrays)
        _arrays = remove(np.array([1, 2, 3]), arrays)
        print(_arrays)
    

提交回复
热议问题