Python pandas:将Series子类存储为DataFrame列

2024-10-04 09:30:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我想创建一个DataFrame,它包含我定义的许多不同的不同的Series子类。然而,当分配给DataFrame时,似乎子类从Series中剥离。在

下面是一个玩具例子来说明这个问题:

>>> 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'

我见过这个问题以前可能已经提过了,但我不知道实际的解决方案。作为一个如此庞大的库,很难遵循各种pr、doc版本等,而且子类化机制似乎没有我所能描述的那么好(this seems to be it)。在


Tags: selfdataframepandasdatareturndefthis子类
2条回答

对于任何有类似需求的人来说:我认为最好的解决方案是定义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

不过,我很想听到任何人有一个更优雅的解决方案!在

我认为除非你还定义了你自己的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不是{}。df.As构造而忽略它是什么类型。在

相关问题 更多 >