I'm trying to build a GeoJSON object. My input is a csv with an address column, a lat column, and a lon column. I then created Shapely points out of the coordinates , buffer them out by a given radius, and get the dictionary of coordinates via the mapping option- so far, so good. Then, after referring to this question, I wrote the following function to get a Series of dictionaries:
def make_geojson(row):
return {'geometry':row['geom'], 'properties':{'address':row['address']}}
and I applied it thusly:
data['new_output'] = data.apply(make_geojson, axis=1)
My resulting column is full of these: <built-in method values of dict object at 0x10...
The weirdest part is, when I directly call the function (i.e. make_geojson(data.loc[0])
I do in fact get the dictionary I'm expecting. Perhaps even weirder is that, when I call the functions I'm getting from the apply (e.g. data.output[0]()
, data.loc[0]['output']()
) I get the equivalent of the following list:
[data.loc[0]['geom'], {'address':data.loc[0]['address']}]
, i.e. the values (but not the keys) of the dictionary I'm trying to get.
For those of you playing along at home, here's a toy example:
from shapely.geometry import Point, mapping
import pandas as pd
def make_geojson(row):
return {'geometry':row['geom'], 'properties':{'address':row['address']}}
data = pd.DataFrame([{'address':'BS', 'lat':34.017, 'lon':-117.959}, {'address':'BS2', 'lat':33.989, 'lon':-118.291}])
data['point'] = map(Point, zip(data['lon'], data['lat']))
data['buffer'] = data['point'].apply(lambda x: x.buffer(.1))
data['geom'] = data.buffer.apply(mapping)
data['output'] = data.apply(make_geojson, axis=1)
Apply a function along an axis of the DataFrame. Objects passed to the function are Series objects whose index is either the DataFrame's index ( axis=0 ) or the DataFrame's columns ( axis=1 ). By default ( result_type=None ), the final return type is inferred from the return type of the applied function.
apply() method. This function acts as a map() function in Python. It takes a function as an input and applies this function to an entire DataFrame. If you are working with tabular data, you must specify an axis you want your function to act on ( 0 for columns; and 1 for rows).
You can use the loc and iloc functions to access columns in a Pandas DataFrame. Let's see how. If we wanted to access a certain column in our DataFrame, for example the Grades column, we could simply use the loc function and specify the name of the column in order to retrieve it.
get_value() function is used to quickly retrieve the single value in the data frame at the passed column and index. The input to the function is the row label and the column label.
Thanks, DSM, for pointing that out. Lesson learned: pandas is not good for arbitrary Python objects
So this is what I wound up doing:
temp = zip(list(data.geom), list(data.address))
output = map(lambda x: {'geometry': x[0], 'properties':{'address':x[1]}}, temp)
I got to this post because I ran into a similar issue, but when running a PySpark DataFrame instead of Pandas.
In case someone ends up here, like myself, I'll explain how I fixed it for a PySpark DataFrame.
The reason why I was getting the error (built-in method of Row object
, in my case), was because my field name count
was colliding with the inherited method count from python tuples (as seen here).
The solution was simply change the name of the field to something like my_count
and it worked fine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With