python/pandas:数据帧继承和数据帧更新(当“就地”不可能时)

2024-09-30 08:31:29 发布

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

对不起,我知道标题有点模糊

上下文

我使用一个Dataframe来跟踪文件,因为pandas DataFrame具有几个相关的函数来完成dict无法完成的所有类型的过滤,其中locpd.IndexSlice.index.columnspd.MultiIndex。。。 好的,这可能不是专家开发人员的最佳选择(我不是),但是所有这些函数都非常方便,所以我开始使用DataFrame来实现这一点。 当我想知道文件列表中的内容时,多索引Dataframe__repr__非常完美

快速介绍Summary类,继承自DataFrame

因为我的DataFrame,我称之为'Summary',有一些特定的函数,我想把它变成一个类,从pandas DataFrame类继承。 它还具有行和列的“固定”多索引

最后,因为我的Summary类是在实际管理文件组织的Store类之外定义的,所以Summary类需要一个来自Store的函数才能检索文件组织

问题

pd.DataFrame的问题是(AFAIK),如果不创建新的DataFrame,则无法追加行。 由于Summary有一个refresh函数,因此它可以通过读取文件夹内容来recreate自身refresh以某种方式“重置”“摘要”对象。 为了管理Summary刷新,我提出了第一个代码(不工作),最后是第二个代码(工作)

import pandas as pd
import numpy as np

# Dummy function
def summa(a,b):
    return a+b

# Does not work
class DatF1(pd.DataFrame):

    def __init__(self,meth,data=None):
        cmidx = pd.MultiIndex.from_arrays([['Index', 'Index'],['First', 'Last']])
        rmidx = pd.MultiIndex(levels=[[],[]], codes=[[],[]],
                              names=['Component','Interval'])
        super().__init__(data=data, index=rmidx, columns=cmidx, dtype=np.datetime64)
        self.meth=meth

    def refresh(self):
        values = [[pd.Timestamp('2020/02/10 8:00'),pd.Timestamp('2020/02/10 8:00')],
                  [pd.Timestamp('2020/02/11 8:00'),pd.Timestamp('2020/02/12 8:00')]]
        rmidx = pd.MultiIndex.from_arrays([['Comp1','Comp1'],['1h','1W']],names=['Component','Interval'])
        self = pd.DataFrame(values, index=rmidx, columns=self.columns)

ex1 = DatF1(summa)

In [10]: ex1.meth(3,4)
Out[10]: 7

ex1.refresh()
In [11]: ex1
Out[11]: Empty DatF1
         Columns: [(Index, First), (Index, Last)]
         Index: []

refresh()之后,ex1仍然是空的refresh工作不正常

# Works
class DatF2(pd.DataFrame):

    def __init__(self,meth,data=None):
        cmidx = pd.MultiIndex.from_arrays([['Index', 'Index'],['First', 'Last']])
        rmidx = pd.MultiIndex(levels=[[],[]], codes=[[],[]],
                              names=['Component','Interval'])
        super().__init__(data=data, index=rmidx, columns=cmidx, dtype=np.datetime64)
        self.meth=meth

    def refresh(self):
        values = [[pd.Timestamp('2020/02/10 8:00'),pd.Timestamp('2020/02/10 8:00')],
                  [pd.Timestamp('2020/02/11 8:00'),pd.Timestamp('2020/02/12 8:00')]]
        rmidx = pd.MultiIndex.from_arrays([['Comp1','Comp1'],['1h','1W']],names=['Component','Interval'])
        super().__init__(values, index=rmidx, columns=self.columns)

    ex2 = DatF2(summa)

    In [10]: ex2.meth(3,4)
    Out[10]: 7

    ex2.refresh()
    In [11]: ex2
    Out[11]:                                  Index                    
                                              First                Last
             Component Interval                                        
             Comp1     1h       2020-02-10 08:00:00 2020-02-10 08:00:00
                       1W       2020-02-11 08:00:00 2020-02-12 08:00:00

这个代码有效

我有两个问题:

  • 为什么第一个代码不起作用?(很抱歉,这可能是显而易见的,但我完全不知道它为什么不起作用)

  • 在我的refresh方法中调用super().__init__可以接受吗?(或者换一种说法:在我的子类的super().__init__之外的其他地方调用super().__init__是否可以接受?)

非常感谢你的帮助和建议。类继承的世界对我来说是一个全新的世界,而且DataFrame内容不能直接修改这一事实,也就是说,对我来说,似乎使它更难处理

祝你过得愉快, 最好的

添加新行时出现错误消息

import pandas as pd
import numpy as np

# Dummy function
def new_rows():
    return [['Comp1','Comp1'],['1h','1W']]

# Does not work
class DatF1(pd.DataFrame):

    def __init__(self,meth,data=None):
        cmidx = pd.MultiIndex.from_arrays([['Index', 'Index'],['First', 'Last']])
        rmidx = pd.MultiIndex(levels=[[],[]], codes=[[],[]],
                          names=['Component','Interval'])
        super().__init__(data=data, index=rmidx, columns=cmidx, dtype=np.datetime64)
        self.meth=meth

    def refresh(self):
        values = [[pd.Timestamp('2020/02/10 8:00'),pd.Timestamp('2020/02/10 8:00')],
                  [pd.Timestamp('2020/02/11 8:00'),pd.Timestamp('2020/02/12 8:00')]]
        rmidx = self.meth()
        self[rmidx] = values

ex1 = DatF1(new_rows)
ex1.refresh()

KeyError: "None of [MultiIndex([('Comp1', 'Comp1'),\n            (   '1h',    '1W')],\n           names=['Component', 'Interval'])] are in the [index]"

Tags: columnsselfdataframedataindexinitdefrefresh
1条回答
网友
1楼 · 发布于 2024-09-30 08:31:29

回答你的问题

why the 1st code is not working?

您正在尝试调用继承自的类。老实说,我不知道你的情况到底发生了什么。我认为这会产生一个错误,但您得到了一个空的数据帧

is calling super().__init__ in my refresh method acceptable coding practise?

可能存在一个合法的用例,用于在_init__()方法之外调用super().__init__。但你的案子不在其中。您已经在您的_uinit中继承了来自的所有内容。为什么要再次使用它


更好的解决方案

你的问题的解决方案出人意料地简单。因为您可以append a row to a Dataframe

df['new_row'] = [value_1, value_2, ...]

或者在使用多索引的情况下(请参见this SO post):

  df.loc[('1h', '1W'), :] = [pd.Timestamp('2020/02/10 8:00'), pd.Timestamp('2020/02/10 8:00')]

最佳做法

您不应该从pd.DataFrame继承。如果要扩展熊猫,请使用documented API

相关问题 更多 >

    热门问题