我想定义一个具有超级pd.DataFrame对象的类,如下所示:
import pandas as pd
class my_data_frame(pd.DataFrame):
def __init__(self, index, columns):
super(my_data_frame,self).__init__(index = index, columns = columns)
self = self.fillna(0)
print('init',self)
df = my_data_frame([1,2,3],['a','b','c'])
print('first', df)
这将打印输出
init a b c
1 0 0 0
2 0 0 0
3 0 0 0
first a b c
1 NaN NaN NaN
2 NaN NaN NaN
3 NaN NaN NaN
所以问题是为什么第5行的fillna函数不能真正起作用。因为从init函数打印它似乎工作,但在命令行中它不起作用。
答案 0 :(得分:1)
使用inplace = True由于某种原因起作用:
class my_data_frame(pd.DataFrame):
def __init__(self, index, columns):
super(my_data_frame,self).__init__(index = index, columns = columns)
self.fillna(0, inplace=True)
print('init',self)
my_data_frame([1,4,3],['a','b','c'])
init a b c
1 0 0 0
4 0 0 0
3 0 0 0
Out[557]:
a b c
1 0 0 0
4 0 0 0
3 0 0 0
我认为这与作业有关。当您使用self =时,它会创建一个新的DataFrame并分配给您的自定义类,但超类没有更新。
答案 1 :(得分:1)
super
的调用,以避免fillna
以下是我在第1项中使用链接的方式。
一个。我创建了一个将参数直接传递给DataFrame构造函数的类
湾我想看看data
是否通过,如果不通过,我将其设置为零
C。我创建了一个属性(@property)来定义构造函数是什么。这是大熊猫在创建新副本时使用的原因。因为我定义了一个直接传递所有参数的子类,所以这应该是非常干净的
d。我定义了一个实现初始化程序意图的函数。
import pandas as pd
class MyDataFrame(pd.DataFrame):
def __init__(self, *args, **kwargs):
if len(args) == 0:
kwargs.setdefault('data', 0)
super(MyDataFrame, self).__init__(*args, **kwargs)
@property
def _constructor(self):
return MyDataFrame
def my_data_frame(index, columns):
return MyDataFrame(index=index, columns=columns)
演示
mdf = my_data_frame([1,4,3],['a','b','c'])
mdf
a b c
1 0 0 0
4 0 0 0
3 0 0 0
mdf2 = mdf[['a', 'c']]
mdf2
a c
1 0 0
4 0 0
3 0 0
type(mdf2)
__main__.MyDataFrame
答案 2 :(得分:0)
我知道从数据框继承是非常诱人的,但事实并非如此。这是您将遇到的许多问题之一。可能最常见的是许多函数返回“新鲜”的数据帧。所以你在new_dataframe上使用一个方法,它将返回一个普通的数据帧。
此外,您的示例不起作用,因为一旦您分配给自我python将其视为局部变量。