2 votes

Problem deleting array elements: "cannot delete array elements".

I have a problem that I can't find a solution to no matter how many times I think about it. I have a program in which I generate a series of data and store them in a list. Later on I have to delete some of the items in the list to make it smaller in size. I always remove the first or last item in the list and I use the "del" or "pop" functions.

To generate the list I want to work on, I call a function I created that returns a list. Something like this:

y = generadatos(a1,a2,a3)
del y[0]

When it reaches the line with the "del" the program hangs. I have tried to do it from the console by typing del y[0] and I get the following error:

ValueError: cannot delete array elements

However if I open a new sheet and create this simple code it works without problems:

del a[0]

print a

If instead of using "del" I use "pop" the same thing happens. I thought that maybe the list returned by the function that generates the data does something that I don't understand and that's why it doesn't let me delete elements.

Any ideas?

Thank you very much.


The "generadata" function is this:

def generadatos(nst,p0st,ast,lbst,timesstrst,pvst,incremst):
xbigst = 0
xsmallst = 0

I0bigst = []
I0smallst = []

for ist in range(0,nst+1):
    pst = p0st + ast*ist

    pbigst = np.abs((pst*pvst)/(pst-pvst))
    psmallst = np.abs((pst*pvst)/(pst+pvst))

    limitpbigst = pbigst/lbst          
    limitpbigst = np.int(limitpbigst)
    halflimitpbigst = np.int(limitpbigst/2)

    limitpsmallst = psmallst/lbst          
    limitpsmallst = np.int(limitpsmallst)
    halflimitpsmallst = np.int(limitpsmallst/2)

    for jst in range(0,timesstrst):
        for kst in range(0,halflimitpbigst):
            xbigst = xbigst + 1

        for lst in range(halflimitpbigst,limitpbigst):
            xbigst = xbigst + 1

        for mst in range(0,halflimitpsmallst):
            xsmallst = xsmallst + 1

        for ost in range(halflimitpsmallst,limitpsmallst):
            xsmallst = xsmallst + 1            

limitpbig2st = np.int((pbigst/2)/lbst)
for qst in range (0,limitpbig2st):
    del I0bigst[-1]

limitpsmall2st = np.int((psmallst/2)/lbst)
for rst in range (0,limitpsmall2st):
    del I0smallst[-1]

if incremst > 0:
    aux1st = I0bigst[::]
    I0bigst = aux1st[::-1]
    aux1st = I0smallst[::]
    I0smallst = aux1st[::-1]

I0st = np.append(I0smallst,I0bigst)

return I0st`

At first I create empty lists in the style of I0 = [] . Then I add data to it using `I0.append(value) And at the end I use NumPy's function I0st = np.append(I0smallst,I0bigst)

return I0st


FJSevilla Points 29084

NumPy arrays are not resizable and do not allow dynamic typing. This is because efficiency is sought, using compiled C code below in the most straightforward way possible. This implies that resizing an array means creating a new array. This is why del does not work.

There are two ways to remove elements from a NumPy array, both involve creating a copy of the array and it is this copy that is returned (because as mentioned above it is not possible to do inplace):

- Using the method numpy.delete

    >>> import numpy as np

    # Eliminar el primer elemento:
    >>> a = np.array([1, 2, 3, 4])
    >>> a = np.delete(a, 0)
    >>> a
    array([2, 3, 4])

    # Eliminar el último elemento
    >>> a = np.array([1, 2, 3, 4])
    >>> a = np.delete(a, a.shape[0] - 1)
    >>> a
    array([1, 2, 3])

    # Eliminar el primero y el último:

    >>> a = np.array([1, 2, 3, 4])
    >>> a = np.delete(a, (0, a.shape[0] - 1))
    >>> a
    array([2, 3])

It receives three parameters:

  1. The array as the first argument.

  2. The index (or iterable with the indexes) of the element(s) to be deleted as the second argument.

  3. The axis on which the third party acts.

Note: In the future (according to the developers themselves) np.delete will allow the use of negative indices, so we will be able to change a = np.delete(a, a.shape[0] - 1) by a = np.delete(a,- 1) .

- Use slicing techniques on the array. This option is usually more efficient, especially if we only remove from the beginning or the end of the array:

    >>> import numpy as np

    #Eliminar el primer elemento
    >>> a = np.array([1, 2, 3, 4])
    >>> a = a[1:]
    >>> a
    array([2, 3, 4])

    # Eliminar el último elemento
    >>> a = np.array([1, 2, 3, 4])
    >>> a = a[:-1]
    >>> a
    array([1, 2, 3])

    # Eliminar el primero y el último:
    >>> a = np.array([1, 2, 3, 4])
    >>> a = a[1:-1]
    >>> a
    array([2, 3])

If you intended to use the element returned by list.pop In this case you must first obtain the element by indexing and then apply the elimination with one of the two methods.

It would also be possible to convert the array to a list or a queue (if add and remove operations are going to predominate at the ends), bearing in mind that there may be implications for type switching and efficiency penalties when switching to using a list or similar (in addition to not being able to use NumPy's own methods with it):

>>> import numpy as np

>>> a = np.array([1, 2, 3, 4])
>>> a = a.tolist() 
>>> a
[1, 2, 3, 4]

>>> a.pop()
>>> a
[1, 2, 3]

>>> del(a[0])
>>> a
>>> [2, 3]

If you are not interested in using NumPy arrays you should simply make your function return a list. If I0s is simply the result of concatenating two lists, as you seem to indicate in the code, just do just that:

>>> I0smallst = [1]
>>> I0bigst = [2,  5]
>>> I0s = I0smallst + I0bigst
>>> [1, 2, 5]


HolaDevs is an online community of programmers and software lovers.
You can check other people responses or create a new question if you don't find a solution

Powered by: