2

I haven't been able to find anything about this value error online and I am at a complete loss as to why my code is eliciting this response.

I have a large dictionary of around 50 keys. The value associated with each key is a 2D array of many elements of the form [datetime object, some other info]. A sample would look like this:

{'some_random_key': array([[datetime(2010, 10, 26, 11, 5, 28, 157404), 14.1],
                           [datetime(2010, 10, 26, 11, 5, 38, 613066), 17.2]],
                          dtype=object), 
'some_other_key':  array([[datetime(2010, 10, 26, 11, 5, 28, 157404), 'true'],
                          [datetime(2010, 10, 26, 11, 5, 38, 613066), 'false']], 
                         dtype=object)}

What I want my code to do is to allow a user to select a start and stop date and remove all of the array elements (for all of the keys) that are not within that range.

Placing print statements throughout the code I was able to deduce that it can find the dates that are out of range, but for some reason, the error occurs when it attempts to remove the element from the array.

Here is my code:

def selectDateRange(dictionary, start, stop):

    #Make a clone dictionary to delete values from 
    theClone = dict(dictionary)

    starting = datetime.strptime(start, '%d-%m-%Y')   #put in datetime format
    ending   = datetime.strptime(stop+' '+ '23:59', '%d-%m-%Y %H:%M')    #put in datetime format 

    #Get a list of all the keys in the dictionary
    listOfKeys = theClone.keys()

    #Go through each key in the list
    for key in listOfKeys:
        print key 

        #The value associate with each key is an array
        innerAry = theClone[key]

        #Loop through the array and . . .
        for j, value in enumerate(reversed(innerAry)):

            if (value[0] <= starting) or (value[0] >= ending):
            #. . . delete anything that is not in the specified dateRange

                del innerAry[j]

    return theClone

This is the error message that I get:

ValueError: cannot delete array elements

and it occurs at the line: del innerAry[j]

Please help - perhaps you have the eye to see the problem where I cannot.

Thanks!

2 Answers 2

6

If you use numpy arrays, then use them as arrays and not as lists

numpy does comparison elementwise for the entire array, which can then be used to select the relevant subarray. This also removes the need for the inner loop.

>>> a = np.array([[datetime(2010, 10, 26, 11, 5, 28, 157404), 14.1],
                  [datetime(2010, 10, 26, 11, 5, 30, 613066), 17.2],
                  [datetime(2010, 10, 26, 11, 5, 31, 613066), 17.2],
                  [datetime(2010, 10, 26, 11, 5, 32, 613066), 17.2],
                  [datetime(2010, 10, 26, 11, 5, 33, 613066), 17.2],
                  [datetime(2010, 10, 26, 11, 5, 38, 613066), 17.2]],
                          dtype=object)
>>> start = datetime(2010, 10, 26, 11, 5, 28, 157405)
>>> end = datetime(2010, 10, 26, 11, 5, 33, 613066)

>>> (a[:,0] > start)&(a[:,0] < end)
array([False,  True,  True,  True, False, False], dtype=bool)
>>> a[(a[:,0] > start)&(a[:,0] < end)]
array([[2010-10-26 11:05:30.613066, 17.2],
       [2010-10-26 11:05:31.613066, 17.2],
       [2010-10-26 11:05:32.613066, 17.2]], dtype=object)

just to make sure we still have datetimes in there:

>>> b = a[(a[:,0] > start)&(a[:,0] < end)]
>>> b[0,0]
datetime.datetime(2010, 10, 26, 11, 5, 30, 613066)
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you! This is a really nice solution to the problem.
I have the same problem, so we cannot delete an element of numpy array? Why is that so?
It's possible to delete rows or columns numpy.org/doc/stable/reference/generated/numpy.delete.html but arrays in contrast to lists are not designed for that and numpy needs to make a copy. This is especially inefficient if you do it repeatedly in a loop.
3

NumPy arrays are fixed in size. Use lists instead.

3 Comments

Thanks! I can't believe I didn't find much documentation on that fact... especially since an array object has a .__delitem__ function... confusing. Either way, thanks. I think I'll go ahead and use lists for the deleting.
Of course it has a __delitem__() method. But as you've discovered, its only purpose is to raise an exception.
@mshell_lauren: Another option that might work for you is numpy.delete, although note that this is not an in-place delete - a new array is returned.

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.