如何将类属性设为DataFrame?遇Pandas警告及self未定义问题求助
问题描述
希望创建对象时传入数据集,通过对象方法操作并修改数据集,示例调用如下:
my_obj = study.Study(one_study, a, b) my_obj.addDate()
尝试第一段代码后出现警告:
import pandas as pd class Study(pd.DataFrame): def __init__(self, oneStudy, m_flag, s_flag): super().__init__(oneStudy) # 继承DataFrame属性 self.stdyData = pd.DataFrame(oneStudy, copy=True) self.stdyData.reset_index(inplace = False, drop = True)
UserWarning: Pandas doesn't allow columns to be created via a new attribute name.
替换self.stdyData = pd.DataFrame(oneStudy, copy=True)为self.stdyData = oneStudy.copy()后,警告仍存在。
修改代码后又出现语法错误:
import pandas as pd class Study(pd.DataFrame): def __init__(oneStudy, m_flag, s_flag): super().__init__(oneStudy) # 继承DataFrame属性 self.stdyData = pd.DataFrame(oneStudy, copy=True) self.stdyData.reset_index(inplace = False, drop = True)
IDE提示:self未定义
解决方案
1. 先解决「self未定义」的语法错误
类的__init__构造方法第一个参数必须是self,这是Python类的语法规则,补上即可:
def __init__(self, oneStudy, m_flag, s_flag):
2. 解决Pandas属性警告问题
Pandas的DataFrame类会把实例属性当作列名处理,直接添加自定义属性(比如stdyData)会触发冲突警告,有两种靠谱的解决思路:
思路一:用组合代替继承(推荐)
不要让Study继承DataFrame,而是把数据集作为类的内部属性持有,完全避开Pandas的内部逻辑冲突:
import pandas as pd class Study: def __init__(self, oneStudy, m_flag, s_flag): # 保存数据集副本,避免修改原数据 self.stdyData = pd.DataFrame(oneStudy, copy=True) self.stdyData.reset_index(inplace=True, drop=True) self.m_flag = m_flag self.s_flag = s_flag def addDate(self): # 这里编写操作数据集的业务逻辑,比如新增日期列 self.stdyData['date'] = pd.date_range(start='2024-01-01', periods=len(self.stdyData)) # 使用示例 one_study = pd.DataFrame({'col1': [1,2,3], 'col2': [4,5,6]}) my_obj = Study(one_study, a=1, b=2) my_obj.addDate() print(my_obj.stdyData)
思路二:如果必须继承DataFrame,注册自定义属性
Pandas提供了_metadata列表,用来声明自定义属性,告诉Pandas这些不是列名:
import pandas as pd class Study(pd.DataFrame): # 注册自定义属性,避免被当作列名处理 _metadata = ['stdyData', 'm_flag', 's_flag'] def __init__(self, oneStudy, m_flag, s_flag): super().__init__(oneStudy) # 基于自身创建数据集副本 self.stdyData = self.copy() self.stdyData.reset_index(inplace=True, drop=True) self.m_flag = m_flag self.s_flag = s_flag def addDate(self): # 可以直接修改自身(继承的DataFrame),也可以修改副本stdyData self['date'] = pd.date_range(start='2024-01-01', periods=len(self)) self.stdyData['date'] = pd.date_range(start='2024-01-01', periods=len(self.stdyData)) # 使用示例 one_study = pd.DataFrame({'col1': [1,2,3], 'col2': [4,5,6]}) my_obj = Study(one_study, a=1, b=2) my_obj.addDate() print(my_obj) print(my_obj.stdyData)
内容的提问来源于stack exchange,提问作者Curious12345
相关产品推荐
相关产品推荐

