In my project I build a class with pandas DataFrame as a core. The values in dataframe depends upon some specification and I initialise it with some letter representing the data I want to work with. I put all my functions to create dataframe inside an __init__ as I understand this functions are one off only and no needs for them after the initialisation. Also I don’t want to have access to this functions after my class is in use in later code. (I am not sure if this is “pythonic” way to do so).
After building basic class with __str__ and plotData() methods I would like to apply some filters and build a new class where additional column is the filter. I would like to do that in __init__ but keep everything what already was done. In another words I don’t want to re-write the whole __init__ only want to add new column to the basic dataframe.
In similar fashion I would like to add an additional plot in the plotData() function
My original code has already quite a few of lines but the principles are very similar to code listed below.
import pandas as pd
import pylab as pl
class myClass(object):
def __init__(self, frameType = 'All'):
def method1():
myFrame = pd.DataFrame({'c1':[1,2,3],'c2':[4,5,6],'c3':[7,8,9]})
return myFrame
def method2():
myFrame = pd.DataFrame({'c1':[.1,.2,.3],'c2':[.4,.5,.6],'c3':[.7,.8,.9]})
return myFrame
def makingChiose(self):
if self.frameType == 'All':
variable = method1() + method2()
elif self.frameType == 'a':
variable = method1()
elif self.frameType == 'b':
variable = method2()
else:
variable = pd.DataFrame({'c1':[0,0,0],'c2':[0,0,0],'c3':[0,0,0]})
#print 'FROM __init__ : %s' % variable
return variable
self.frameType = frameType
self.cObject = makingChiose(self) # object created by the class
def __str__(self):
return str(self.cObject)
def plotData(self):
self.fig1 = pl.plot(self.cObject['c1'],self.cObject['c2'])
self.fig2 = pl.plot(self.cObject['c1'],self.cObject['c3'])
pl.show()
class myClassAv(myClass):
def addingCol(self):
print 'CURRENT cObject \n%s' % self.cObject # the object is visible
self.cObject['avarage'] = (self.cObject['c1']+self.cObject['c2']+self.cObject['c3'])/3
print 'THIS WORKS IN GENERAL\n%s' % str((self.cObject['c1']+self.cObject['c2']+self.cObject['c3'])/3) # creating new column works
def plotData(self):
# Function to add new plot to already existing plots
self.fig3 = pl.plot(self.cObject['c1'],self.cObject['avarage'])
if __name__ == '__main__':
myObject1 = myClass()
print 'myObject1 =\n%s' % myObject1
myObject1.plotData()
myObject2 = myClass('a')
print 'myObject2 =\n%s' % myObject2
myObject3 = myClass('b')
print 'myObject3 =\n%s' % myObject3
myObject4 = myClass('c')
print 'myObject4 =\n%s' % myObject4
myObject5 = myClassAv('a').addingCol()
print 'myObject5 =\n%s' % myObject5
myObject5.plotData()
Most of the code works, at least in the initialisation but I have an error when I try to create new dataframe with additional column. When I put as the new __init__ I create a completely new initialisation and I loose all what was already done. I created a new function but I would prefer have the additional column after I call a new class not a function inside the new class The output from the code looks like this:
myObject1 =
c1 c2 c3
0 1.1 4.4 7.7
1 2.2 5.5 8.8
2 3.3 6.6 9.9
myObject2 =
c1 c2 c3
0 1 4 7
1 2 5 8
2 3 6 9
myObject3 =
c1 c2 c3
0 0.1 0.4 0.7
1 0.2 0.5 0.8
2 0.3 0.6 0.9
myObject4 =
c1 c2 c3
0 0 0 0
1 0 0 0
2 0 0 0
CURRENT cObject
c1 c2 c3
0 1 4 7
1 2 5 8
2 3 6 9
THIS WORKS IN GENERAL
0 4
1 5
2 6
myObject5 =
None
Traceback (most recent call last):
File "C:\Users\src\trys.py", line 57, in <module>
myObject5.plotData()
AttributeError: 'NoneType' object has no attribute 'plotData'
The question is: Can I ‘partially’ override the superclass’s method to have what was previously inside this method with some new functionality? I would like to initialise myClassAv() to dataframe with four columns instead of three like myClass() and I’d like to have myClassAv().plotData() to plot a third line but keep two from base class.
I don’t know how to interpret an error and why myObject5 is None, but I suspect it is something with inheritance.
Also if you have suggestion that I should do all my idea in different way I will appreciate to hear them.
How about just call
myClass.__init__insidemyClassAv.__init__:For concreteness,
By the way, instead of
you can use
mean(axis = 1):