我想创建一个DataFrame
,其中包含许多我已定义的不同的 Series
子类。但是,当分配给Series
时,似乎从DataFrame
剥离了子类。
这是一个说明问题的玩具示例:
>>> import pandas as pd
>>> class SeriesSubclass(pd.Series):
... @property
... def _constructor(self):
... return SeriesSubclass
... def times_two(self):
... """Method I need in this subclass."""
... return self * 2
...
>>> subclass = SeriesSubclass([7, 8, 9])
>>> type(subclass) # fine
<class '__main__.SeriesSubclass'>
>>> subclass.times_two() # fine
0 14
1 16
2 18
dtype: int64
>>>
>>> data = pd.DataFrame([[1, 2, 3], [4, 5, 6]], columns=list('ABC'))
>>> data['D'] = subclass
>>> type(data['D']) # not good
<class 'pandas.core.series.Series'>
>>> data['D'].times_two() # not good
Traceback (most recent call last):
...
AttributeError: 'Series' object has no attribute 'times_two'
我之前看到此问题可能已被提出#1713,但我无法辨别实际的解决方案。作为一个如此庞大的图书馆,它难以遵循各种PR,doc版本等。而且子类化机制似乎并没有像我所说的那样(this seems to be it)。
答案 0 :(得分:0)
除非您还定义了自己的pd.DataFrame
子类,否则我认为您运气不佳。这将是一项更艰巨的任务。
考虑这个例子
df = pd.DataFrame()
s = pd.Series([1, 2, 3])
s.random_attribute = 'hello!'
print(s.random_attribute)
df['A'] = s
print(df.A.random_attribute)
hello!
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-273-e0031d933193> in <module>()
5
6 df['A'] = s
----> 7 print(df.A.random_attribute)
//anaconda/envs/3.5/lib/python3.5/site-packages/pandas/core/generic.py in __getattr__(self, name)
2742 if name in self._info_axis:
2743 return self[name]
-> 2744 return object.__getattribute__(self, name)
2745
2746 def __setattr__(self, name, value):
AttributeError: 'Series' object has no attribute 'random_attribute'
df.A
不是s
。 df.A
从s
构造,并忽略它的类型。
答案 1 :(得分:0)
为了有类似需求的人的利益:我认为最好的解决方案是定义DataFrame
的子类并使用__getitem__
逻辑进行干预。
我原来的问题是基于假设DataFrame
被实现为容器,从根本上说它不是。它更有活力,例如......
>>> from pandas import Series, DataFrame
>>> s = Series([1, 2, 3, 4], name='x')
>>> df = DataFrame(s)
>>> s is df.x
False
因此,为了将列检索为Series
的子类,您需要修改__getitem__
。
我已在我自己的软件包中实现了这个功能,可以作为示例:https://github.com/jmackie4/activityio/blob/master/activityio/_util/types.py
我很想听到任何人提供更优雅的解决方案!