Reputation: 33
I have an existing dataframe ("radar_locations") which contains (among other things) latitude and longitude coordinates. To that information, I need to add a country and state column, so I've written a function that does a reverse geocode and returns the two values needed return geodata.state, geodata.country
When I try to assign the values into new columns in the dataframe, I get an error that there are too many values to unpack. But if I update the code so that the function returns a single value, I can successfully write that value into a new dataframe column.
If this just an eccentricity of pandas or is there something more fundamental I'm missing?
works
def reverse_geocode(lat, long):
...
return geodata.country
radar_locations['Country'] = radar_locations.apply(lambda x: reverse_geocode(x[1], x[0]), axis=1)
works
def reverse_geocode(lat, long):
...
return geodata.state, geodata.country
state, country = reverse_geocode(mylat, mylong)
fails
def reverse_geocode(lat, long):
...
return geodata.state, geodata.country
radar_locations['State'], radar_locations['Country'] = radar_locations.apply(lambda x: reverse_geocode(x[1], x[0]), axis=1)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-28-82e3c63a2ecb> in <module>()
19 raise
20
---> 21 radar_locations['State'], radar_locations['Country'] = radar_locations.apply(lambda x: reverse_geocode(x[1], x[0]), axis=1)
ValueError: too many values to unpack (expected 2)
Upvotes: 3
Views: 2019
Reputation: 33803
Use zip
and the *
operator to unzip and perform the assignment:
# A function that returns multiple things.
def some_func(x):
return x+1, x+2
# Example DataFrame
df = pd.DataFrame({'A': range(5)})
# Example usage.
df['B'], df['C'] = zip(*df['A'].apply(some_func))
The resulting output:
A B C
0 0 1 2
1 1 2 3
2 2 3 4
3 3 4 5
4 4 5 6
The issue with trying to assign directly from the apply
is that when you return multiple values, you're actually returning a single column of tuples, not two separate columns, which is why the unzipping process is necessary:
df['A'].apply(some_func)
0 (1, 2)
1 (2, 3)
2 (3, 4)
3 (4, 5)
4 (5, 6)
Upvotes: 8