Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pandas apply to dateframe produces '<built-in method values of ...'

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)
like image 699
Nick Marinakis Avatar asked Jan 16 '15 21:01

Nick Marinakis


People also ask

How use pandas DataFrame apply method?

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.

What is the use of apply () in Python?

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).

How do I get the values of a column in a DataFrame?

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.

How do you get a value from a DataFrame in Python?

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.


2 Answers

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)
like image 186
Nick Marinakis Avatar answered Sep 30 '22 05:09

Nick Marinakis


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.

like image 42
Hannon Queiroz Avatar answered Sep 30 '22 06:09

Hannon Queiroz