0

I'm trying to right a code using the Geopy library to get lat long for some adresses.

So I wrote this function:

def latlong(street, city):
    try:
        location = geolocator.geocode(str(street) + ', ' + str(city))
        if location is None:
            return 0, 0
        return location.latitude, location.longitude
    except:
        return 0, 0

df['LAT'], df['LONG'] = df.apply(lambda x: latlong(x['STREET'], x['CITY']), axis = 1)

The code runs for some time and then I get this error:

ValueError: too many values to unpack (expected 2)

However if I change the code to have two function, one for lat and one for long it works just fine, but it takes twice the time to run and I'll do twice as many requests to the API.

def lat(street, cidade):
    location = geolocator.geocode(str(street) + ', ' + str(city))
    if location is None:
        return 0
    return location.latitude

def long(street, cidade):
    location = geolocator.geocode(str(street) + ', ' + str(city))
    if location is None:
        return 0
    return location.longitude

df['LAT'] = df.apply(lambda x: lat(x['STREET'], x['CITY']), axis = 1)
df['LONG'] = df.apply(lambda x: long(x['STREET'], x['CITY']), axis = 1)

Is there a way two call a function using apply and lambda to fill two columns of a dataframe at the same time? How can I fix this 'too many values to unpack' error?

Thanks in advance for the help!

AMC
  • 2,642
  • 7
  • 13
  • 35
eduardoftdo
  • 382
  • 3
  • 13
  • What do you understand from that error message? – AMC Apr 15 '20 at 01:38
  • Does this answer your question? [Return multiple columns from apply pandas](https://stackoverflow.com/questions/23586510/return-multiple-columns-from-apply-pandas) – AMC Apr 15 '20 at 01:39
  • I tried using zip like this: df['LAT'], df['LONG'] = zip(*df[['STREET', 'CITY']].apply(latlong)). And changed the latlong function to return location.latitude, location.longitude but then I get this error: TypeError: latlong() missing 1 required positional argument: 'city'. Not really sure what to change because in the link the function only received one argument – eduardoftdo Apr 15 '20 at 16:42
  • I don't think the number of arguments to the function impacts the solution, try something similar to what you were originally doing with `apply()`. – AMC Apr 15 '20 at 17:55

1 Answers1

0

To avoid making two API calls and to make the program faster, I would first add both lat-long to one column. Then later split it to two columns. Like so,

df['LAT_LOG'] = df.apply(lambda x: latlong(x['STREET'], x['CITY']), axis = 1)
df['LAT'] = df.apply(lambda x: x[0][0], axis=1)
df['LONG'] = df.apply(lambda x: x[0][1], axis=1)

The LAT_LONG column can later be dropped:

del df['LAT_LOG']
quest
  • 3,576
  • 2
  • 16
  • 26
  • I changed the function to return the lat long to a single column return [[location.latitude, location.longitude]] But I'm having some trouble splitting it to create the two new columns This is the results of a single cell: [[-88.9422089, -99.4573285]] If I do str(df['LATLONG']).replace('[', '').replace(']', '').split(',') This is the results I get ['0 -55.9422089', ' -11.4573285\n1 -55.0307727', ' -11.6030093\n2 -55.9351512', ' -11.4650052\n3 -55.9423396', ' -11.4761905\n4 -55.0263128', ' -11.5758951\n ... – eduardoftdo Apr 15 '20 at 16:37
  • from `[[-88.9422089, -99.4573285]]` it seem it is a list of list. So please try `df['LAT'] = df.apply(lambda x: x[0][0], axis=1)`. Similarly for `LONG` – quest Apr 16 '20 at 07:46
  • The problem with x[0][0] is that I'll always get the value from the first cell, I'd need something like x[i][0] where i is the current row. But I don't know how to implement that – eduardoftdo Apr 16 '20 at 23:00
  • no no, with `apply` with `and axis=1` it will do this automatically. Check the modified answer. – quest Apr 17 '20 at 06:43