首页 > 解决方案 > 如何避免熊猫类覆盖?

问题描述

我已经建立了一个包含时间流逝信息的数据集。为了使终端和 Spyder IDE 上的读数更简单,我创建了一个继承自的自定义类,datetime.timedelta它的唯一变化是表示方法(__repr____str__):

from datetime import timedelta

class tdn(timedelta):
    def __repr__(self):
        if self.total_seconds() < 0:
            abst = 'D'
        elif self.total_seconds() > 0:
            abst = 'C'
        else:
            return '{}(0)'.format(self.__class__.__qualname__)
        hh, s1 = divmod(abs(self.total_seconds()), 3600)
        mm = s1 // 60

        return '{}({}, hours={:n}, minutes={:n})'\
            .format(self.__class__.__qualname__, abst, hh, mm)
    
    def __str__(self):
        if self.total_seconds() < 0:
            abst = '-'
        else:
            abst = ''
        hh, s1 = divmod(abs(self.total_seconds()), 3600)
        mm = s1 // 60

        return '{}{:02n}:{:02n}'.format(abst, hh, mm)

但是,当在 Pandas DataFrame 中显式应用时,它将假定的新类转换为 pandas自己的 timedelta 类

In [1]: a = pd.DataFrame(
    {'date':
        {0: datetime.date(2020, 9, 30),
         1: datetime.date(2020, 10, 1),
         2: datetime.date(2020, 10, 2),
         3: datetime.date(2020, 10, 5)},
     'lapse':
        {0: tdn(minutes=31),
         1: tdn(minutes=51),
         2: tdn(minutes=-38),
         3: tdn(minutes=41)}})
Out[1]:
         date             lapse
0  2020-09-30          00:31:00
1  2020-10-01          00:51:00
2  2020-10-02 -1 days +23:22:00
3  2020-10-05          00:41:00

当我们检查该lapse系列时,您可以看到发生了转换:

In [2]: a['lapse'].dtype
Out[2]: dtype('<m8[ns]')

In [3]: type(a.loc[0, 'lapse'])
Out[3]: pandas._libs.tslibs.timedeltas.Timedelta

有什么办法可以避免 pandas 覆盖我的自定义类?我唯一的目标:__str__在终端上调用 DataFrame 时,让该方法按预期出现,而无需使用strftime或类似方法显式转换为字符串。

Obs:使用a['lapse'].astype(tdn)会抛出一个TypeError: dtype '<class '__main__.tdn'>' not understood

标签: pythonpandasinheritance

解决方案


推荐阅读