Reputation: 3379
I have a function that reads in a bunch of raw data with some user-input and compiles it into a Pandas series. In the example below I call it create_data
and it just builds a random Series of length n
.
>>> def create_data(n):
... return pd.Series(np.random.randint(1, 100, n))
...
>>>
>>> function_result=create_data(10)
>>> function_result
0 73
1 91
2 31
3 44
4 19
5 30
6 42
7 56
8 69
9 70
dtype: int32
Then I have a set of functions that want to be able to apply to this series. In this example, I create one that calculates the correlation between the series and its first-degree difference.
>>> def temporal_corr(x):
... return pd.concat([x, x.shift()], 1).corr().iloc[0, 1]
...
I can obviously just apply it to series by calling the function...
>>> temporal_corr(function_result)
0.38714413906049816
But let's say I have several different functions that I want to use on this series. Would it make more sense (or is it possible), to create a class that constructs an object using the function create_data
and then have a set of functions within the class that can be applied as methods? I create a class and define this function below.
>>> class myobj:
... def __init__(self, myobj):
... self.myobj = myobj
...
... def temporal_corr(self):
... return pd.concat([self.myobj, self.myobj.shift()], 1).corr().iloc[0, 1]
...
>>> a = myobj(function_result)
>>> a.temporal_corr()
0.38714413906049816
What is the best way to have the class object myobj
be created as a result of the function create_data
? I would like to be able to call create_data
and have the result be an object from which I can call temporal_corr()
.
Upvotes: 2
Views: 2636
Reputation: 2743
If I understand your question correctly, I think you're looking to do the following:
import pandas as pd
import numpy as np
class MyObjMaker(object):
def __init__(self, n):
self.myobj = pd.Series(np.random.randint(1, 100, n))
def temporal_corr(self):
return pd.concat([self.myobj, self.myobj.shift()], 1).corr().iloc[0, 1]
def create_data(n):
return MyObjMaker(n)
Here, the function create_data
creates an object from the class, and that has your temporal_corr
function. For example, I'd use it as follows:
In [2]: a = create_data(10) # `a` is now an instance of MyObjMaker
In [4]: type(a) # proof that `a` is now an instance of MyObjMaker
Out[4]: __main__.MyObjMaker
In [5]: a.temporal_corr() # `temporal_corr` works
Out[5]: -0.18294239972101703
Jim's solution should be fine too, but it sub-classes off of pd.Series
- if you don't need all the other methods in pd.Series
then there's no point sub-classing off of it.
Upvotes: 2
Reputation: 160427
Essentially you're looking for an object that acts like a Series
but is more specialized, so, just create a class that inherits from pd.Series
:
import pandas as pd
from numpy.random import randint
class mySeries(pd.Series):
def __init__(self, n):
super().__init__(randint(0, 100, n)) # initialize series
# Add your custom methods:
def temporal_corr(self):
return pd.concat([self, self.shift()], 1).corr().iloc[0, 1]
Then, create_data
can be your factory function for your specialized Series
objects:
def create_data(n):
return mySeries(n)
which you can extend and add checks according to your needs.
Upvotes: 2