Error passing numpy.core. _exceptions.Ufunctypeerror: ufunc 'subtract' Did not contain a loop Signature matching types (dtype('<U21')

Asked

Viewed 218 times

1

Basically I have the following code:

import numpy as np

def localize(aux1, aux2, aux3, aux4, aux5, aux6):

    search = np.array([(aux1,aux2,aux3,aux4,aux5,aux6)])

    B1A = np.array([(-46,-78,-72,-70,-81,-59)])     #B1A
    B1B = np.array([(-100,-82,-85,-100,-76,-55)])   #B1B
    B1C = np.array([(-100,-100,-100,-78,-100,-58)]) #B1C
    B2A = np.array([(-100,-88,-100,-100,-100,-60)])  #B2A
    B2B = np.array([(-100,-78,-79,-80,-80,-59)])     #B2B

    candidatos = [B1A, B1B, B1C, B2A, B2B]
    margem_erroP = 10.0
    margem_erroN = -10.0

    distancias = candidatos[::] - search

    avaliar_dist = np.where(np.absolute(distancias) < margem_erroP, True, False) 
    avaliar_distN = np.where(np.absolute(distancias) < margem_erroN, True, False)

    vetores_aprovados = avaliar_dist.all(axis=2)
    vetores_aprovados += avaliar_distN.all(axis=2)

    posicao_aprovados = np.array(np.where(vetores_aprovados== True)[0])

    print("---- Resultado ----")
    print()
    print("Busca: {}".format(search))
    print("Resultado: ")
    for x in posicao_aprovados:
        print(candidatos[x])

        here = candidatos[x][-1]
        print("Aquii")
        print(here)

        if posicao_aprovados[0] == 0:
            print("Local: B1A")
            local = "B1A"
        elif posicao_aprovados[0] == 1:
            print("Local: B1B")
            local = "B1B"
        elif posicao_aprovados[0] == 2:
            print("Local: B1C")
            local = "B1C"
        elif posicao_aprovados[0] == 3:
            print("Local: B2A")
            local = "B2A"
        elif posicao_aprovados[0] == 4:
            print("Local: B2B")
            local = "B2B"
        else:
            local = "não encontrado"

    x = {
        "search" : search.tolist(),
        "locale" : local,
        "result" : here.tolist()
    }
    json.dumps(x)
    return x

So far so good, works right as needed!

The problem is when I try to perform this function from another location. For example:

I have a variable find containing the following string: '-100,-67,-63,-49,-53,-48'

Since I need to pass 6 values and in this case I am passing only 1 (a string) I separate my string into integers using the following command: valores = find.split(",")

Done that now my list becomes that: ['-100', '-67', '-63', '-49', '-53', '-48']

To make my function run I did as follows: aux = localize.localize(valores[0],valores[1],valores[2],valores[3],valores[4],valores[5])

Passing this way what I’m doing is basically: localize.localize(-100 -67 -63 -49 -53 -48)

But it does not work by returning the error: distancias = candidatos[::] - search numpy.core._exceptions.UFuncTypeError: ufunc 'subtract' did not contain a loop with signature matching types (dtype('<U21'), dtype('<U21')) -> dtype('<U21')

IMPORTANT TO MENTION THAT If I call my function by directly passing the values in this way: aux = localize.localize(-100,-70,-68,-55,-53,-55) It works perfectly but passing this way another way that is how accurate does not go at all.

I came to think that it was not working because there was no comma separating each integer value so I did it as follows: localize.localize(valores[0]+',',valores[1]+',',valores[2]+',',valores[3]+',',valores[4]+',',valores[5])

That was the same as passing:

localize.localize(-100,-67,-63,-49,-53,-48) which also did not work.

I would like help to understand how I can pass the values in a way that is functional and through the variables as described. Thanks in advance for any help

If it helps, I leave down the function I’m trying to perform. It is a POST of an API that comes with some parameters (coordinates) and the algorithm will help me tell you which is where these coordinates are closest. Only then after receiving the data and checking which location is are the data saved in the database. I was printing everything to see how the hehe data were coming

@app.route('/api/v1/resources/positions/app', methods=['POST'])
def positions_post_app():
    conn = sqlite3.connect('locale.db')
    conn.row_factory = dict_factory
    cur = conn.cursor()
    users = request.get_json()
    for user in users:
        user_id = user['user_id']
        find = user['search']
        date = user['date']

#        print("valor que chega!")
#        print(find)
#        valores = find.split(",")
#        print("lista de inteiros")
#        print(valores)
#        print("Tabela atualizada:")
#        print(valores[0]+',',valores[1]+',',valores[2]+',',valores[3]+',',valores[4]+',',valores[5])

#        aux = localize.localize(-100,-70,-68,-55,-53,-55) #FUNÇÃO FUNCIONANDO
         aux = localize.localize(valores[0],valores[1],valores[2],valores[3],valores[4],valores[5])

        locale = aux['locale']
        result = aux['result']
        print("insert into positions values(NULL, '{}','{}', {}, {}, '{}')".format(user_id, find, result, locale, date)) #PRINT PARA VER COMO FICARIA O SQL 

#        cur.execute("insert into positions values(NULL, '{}','{}', {}, {}, '{}')".format(user_id, search, result, locale, date))
#        conn.commit()
    return {'Status' : 'Success'}

1 answer

1


First thing we’re gonna do is replicate your mistake.

import numpy as np

def localize(aux1, aux2, aux3, aux4, aux5, aux6):

    search = np.array([(aux1,aux2,aux3,aux4,aux5,aux6)])

    B1A = np.array([(-46,-78,-72,-70,-81,-59)])     #B1A
    B1B = np.array([(-100,-82,-85,-100,-76,-55)])   #B1B
    B1C = np.array([(-100,-100,-100,-78,-100,-58)]) #B1C
    B2A = np.array([(-100,-88,-100,-100,-100,-60)])  #B2A
    B2B = np.array([(-100,-78,-79,-80,-80,-59)])     #B2B

    candidatos = [B1A, B1B, B1C, B2A, B2B]


    return candidatos[::] - search #Aqui acontece o erro

find = '-100,-67,-63,-49,-53,-48'

valores = find.split(",")

print(valores)

print(localize(valores[0],valores[1],valores[2],valores[3],valores[4],valores[5]))

returning:

['-100', '-67', '-63', '-49', '-53', '-48']
Traceback (most recent call last):
  File "main.py", line 24, in <module>    print(localize(valores[0],valores[1],valores[2],valores[3],valores[4],valores[5]))
  File "main.py", line 16, in localize    return candidatos[::] - searchnumpy.core._exceptions.UFuncTypeError: 
  ufunc 'subtract' did not contain a loop with signature matching types (dtype('<U21'), dtype('<U21')) -> dtype('<U21')

What has been done?

Simplification of the function localize() leaving only the portion related to the error message. The replica of the way you obtained the values to be passed as parameters for localize() and printing the list valores:

['-100', '-67', '-63', '-49', '-53', '-48']

How can you verify valores is a list of strings and when it does:

return candidatos[::] - search

Get the operation error because the matrix elements candidatos and search are of different types and operator - cannot apply the function numpy.subtract() between integers and strings.

To fix this problem just ensure that when creating the matrix search this matrix will be an integer matrix. To do this in the constructor numpy.array(), determine the data type of the resulting matrix by adjusting the parameter dtype as np.int_:

search = np.array([(aux1,aux2,aux3,aux4,aux5,aux6)], dtype=np.int_)

In the simplified example:

import numpy as np

def localize(aux1, aux2, aux3, aux4, aux5, aux6):

    search = np.array([(aux1,aux2,aux3,aux4,aux5,aux6)], dtype=np.int_) #Agora cria uma matriz de inteiros

    B1A = np.array([(-46,-78,-72,-70,-81,-59)])     #B1A
    B1B = np.array([(-100,-82,-85,-100,-76,-55)])   #B1B
    B1C = np.array([(-100,-100,-100,-78,-100,-58)]) #B1C
    B2A = np.array([(-100,-88,-100,-100,-100,-60)])  #B2A
    B2B = np.array([(-100,-78,-79,-80,-80,-59)])     #B2B

    candidatos = [B1A, B1B, B1C, B2A, B2B]


    return candidatos[::] - search 

find = '-100,-67,-63,-49,-53,-48'

valores = find.split(",")

print(valores)

#Agora funciona com parâmetros string
print(localize(valores[0],valores[1],valores[2],valores[3],valores[4],valores[5]))

#Continua funcionando com parâmetros inteiros
print(localize(-100,-67,-63,-49,-53,-48))

Returning:

['-100', '-67', '-63', '-49', '-53', '-48']
[[[ 54 -11  -9 -21 -28 -11]]
 [[  0 -15 -22 -51 -23  -7]]
 [[  0 -33 -37 -29 -47 -10]] 
 [[  0 -21 -37 -51 -47 -12]] 
 [[  0 -11 -16 -31 -27 -11]]]
[[[ 54 -11  -9 -21 -28 -11]]    
 [[  0 -15 -22 -51 -23  -7]]    
 [[  0 -33 -37 -29 -47 -10]]    
 [[  0 -21 -37 -51 -47 -12]]    
 [[  0 -11 -16 -31 -27 -11]]]

Simplified example working on Repl.it.

OBS: In case I understood being as integer the data type of your operation in case I was wrong and the data are floating point instead of using dtype=np.int_ use dtype=np.float. To others types of data see Numpy Data Types for a list of types of available data.

  • 1

    Augusto perfect! That’s what it was. I knew that for some reason even though I was sending correct numbers something more needed because with the test with numbers directly gave. You saved me well with this answer and very well explained on your part! Yes, they are even integers. I thought that by converting my string list to a whole list it would already work in numpy. Thank you very much

Browser other questions tagged

You are not signed in. Login or sign up in order to post.