serv-inc
serv-inc

Reputation: 38247

Create series from python object, include its @property

To create a pandas.Series from a generic object, the following can be used:

import datetime

class Test(object):
    def __init__(self):
        self.creation = datetime.datetime.now()

a = Test()
c = pandas.Series(a.__dict__)

This results in a Series that is described as

creation   2017-12-17 09:51:48.157503
dtype: datetime64[ns]

This failed to work if the object contains "attributes" created using @property, like so

class Test(object):
    def __init__(self):
        self.creation = datetime.datetime.now()

    @property
    def as_string(self):
        return 'Test at {}'.format(self.creation)

a = Test()
c = pandas.Series(a.__dict__) # same as above

How can the object's properties be included in the Series? Or is there an easier way to create a Series from a generic object, including its properties?

Upvotes: 1

Views: 47

Answers (1)

jakevdp
jakevdp

Reputation: 86433

I would probably do something like this:

def data_properties(obj):
    def _props(obj):
        for attr in dir(obj):
            if attr.startswith('__'):
                continue
            val = getattr(obj, attr)
            if not callable(val):
                yield (attr, val)
    return dict(_props(obj))

You can use it this way:

import datetime
import pandas


class Foo(object):
    def __init__(self):
        self.x = datetime.datetime.now()

    @property
    def y(self):
        return 5

    def method(self, x):
        return self.y * x


f = Foo()
pd.Series(data_properties(f))
# x    2017-12-17 07:09:20.694000
# y                             5
# dtype: object

The benefit of the approach is that the _props generator can be easily modified to fine-tune the results if you have other constraints on what you'd like to have in your resulting series.

Upvotes: 1

Related Questions