我试图弄清楚Pandas如何在飞行中设法创建新的对象成员。例如,如果您这样做:
d = {'col1': [1, 2], 'col2': [3, 4]}
df = pd.DataFrame(data=d)
您可以立即执行此操作:
df.col1
并获取col1
的内容。 Pandas如何动态创建col1
成员?
感谢。
答案 0 :(得分:0)
class DataFrame(NDFrame):
def __init__(self, data=None, index=None, columns=None, dtype=None,
copy=False):
if data is None:
data = {}
# Some other if-statements that check data types...
elif isinstance(data, dict): mgr = self._init_dict(data, index, columns, dtype=dtype)
def _init_dict(self, data, index, columns, dtype=None):
if columns is not None:
# Does some stuff - but this isn't your case
else:
keys = list(data.keys())
if not isinstance(data, OrderedDict):
# So this part is trying to sort keys to cols in alphabetical order
# The _try_sort function is simple, exists in pandas.core.common
keys = _try_sort(keys)
columns = data_names = Index(keys)
所以真正的工作来自pandas.core.indexes.base中的Index class。从那里开始变得非常复杂(并且我理解解释任何东西的“方式”意味着什么而不会继续回归,直到你得到机器代码,开始融化)但是可以肯定地说,如果你给了它pandas.Index
类是一维数据数组,它将创建一个具有可切片集和关联数据类型的对象。
这正是你所观察到的 - 你基本上给它提供了一堆密钥,而pandas
知道它需要给你一些你可以作为索引访问的东西(因为df.col1
是只是df['col1']
)的语法糖,你可以切片(df[0:1]
),并且知道它自己的数据类型。
答案 1 :(得分:0)
当然,在提出问题之后,我自己找到了答案。
事实证明,您可以使用__getattr__
来实现这一目标。最简单的方法(也是我想要的方法)是使用字典,然后使用__getattr__
返回字典中的值,如下所示:
class test():
def __init__(self):
# super().__init__()
self.adict = {'spam' : 'eggs'}
def __getattr__(self, attr):
return self.adict[attr]
nt = test()
print(nt.spam)
找不到类属性时会调用 __getattr__
,就像这里的情况一样。解释器无法找到spam
属性,因此将其推迟到__getattr__
。要记住的事情:
__getattribute__
,因为每次调用属性时都会调用它,从而弄乱整个班级。感谢大家对此的意见。