在pandas dataframe子类中设置索引

2024-10-04 01:22:48 发布

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

我想做的是:

我目前正在使用python3构建pandasDataFrame的子类。该类的一个特性是用户输入其data以及在构造时用于为类创建MultiIndex的列的名称。然而,我正在努力寻找一个干净的方法来做这件事。在

失败的策略#1

我的第一次尝试如下所示,在这里,我尝试在调用DataFrame构造函数之前构造数据和索引值:

class DFSubClass(pd.DataFrame):
    @property
    def _constructor(self):
        return DFSubClass

    def __init__(self, data=None, #other DataFrame parameters#,
                 col_for_multi_index = None):

        multi_index = CreateMultiIndex(data, col_for_multi_index)
        data_subset = RemoveIndexColumnsFromData(data, col_for_multi_index)

        super(DFSubClass,self).__init__(data = data_subset,
                                                 index = multi_index,
                                                 #other DataFrame parameters#)

        multi_index = ComputeMultiIndexFromColumns(data, col_for_multi_index)

        self = self.set_index(multi_index)

虽然我能做一些我认为对ComputeMultiIndexFromColumns()有用的东西:

^{pr2}$

我无法为RemoveIndexColumnsFromData()找到任何可以干净地处理pandas构造函数可以接受的所有不同数据类型(即numpy arraysdicts,其他DataFrame)。另外,当输入是DataFrame时,我遇到了this problem,其中构造函数返回所有NaN,因为之前的索引与新的index值不匹配。在

失败的策略#2

此时,我决定不重新设计轮子,让pandas包处理这些问题,方法是首先调用DataFrame构造函数,然后使用set_index()功能重新索引我的数据:

class DFSubClass(pd.DataFrame):
    @property
    def _constructor(self):
        return DFSubClass

    def __init__(self, data=None, #other DataFrame parameters#,
                 col_for_multi_index = None):

        super(DFSubClass,self).__init__(data = data,
                                                 #other DataFrame parameters#)

        multi_index = ComputeMultiIndexFromColumns(data, col_for_multi_index)

        self = self.set_index(multi_index)

神圣的无限递归蝙蝠侠!结果是set_index()函数调用构造函数来重新索引DataFrame,这意味着这个函数永远都在调用自己。在

我现在在哪里

我觉得有点卡住了。回到第一个策略似乎是我需要做的,但是我对处理所有数据类型有点犹豫,特别是当pandas已经解决了这个问题时。如果有人知道我是如何1)利用pandas中已有的功能来干净利落地完成这项工作,或者2)另一种解决这个问题的策略,我将不胜感激。在


Tags: selfnonedataframefordataindexinitdef
1条回答
网友
1楼 · 发布于 2024-10-04 01:22:48

这个键最终使用了inplace=True,所以我最后的类定义如下所示。在

class DFSubClass(pd.DataFrame):

    @property
    def _constructor(self):
        return DFSubClass

    def __init__(self, data=None, #other DataFrame parameters#,
                 col_for_multi_index = None):

        super(DFSubClass,self).__init__(data = data
                                        #, other DataFrame parameters#
                                        )

        self = self.set_index(col_for_multi_index, inplace = True)

inplace=True阻止构造函数被调用,并防止无限递归问题。在

请注意,如果data对象已经有索引集,这将从数据中删除这些列。如果您希望将这些列重置为DFSubClass,则需要首先调用reset_index(inplace=True)。但是,这有一个缺点,如果索引只是默认索引,reset_index()将在DFSubClass中给您一个新列,该列的值从0到DFSubClass.size[0]。以下代码可防止这种情况发生:

^{pr2}$

但是,如果索引是继承自Int64Index的任何类,比如DateTimeIndex,那么这也会阻止对reset_index()的调用。我还没有找到一个干净的方法来解决这个问题,所以目前我只有一个函数来检查self.index是否是pd.Int64Index,但我所知的其他类中除了pd.RangeIndex之外,没有任何其他类是从pd.Int64Index继承的。在

相关问题 更多 >