Python中的重载 - pandas

2 投票
2 回答
2127 浏览
提问于 2025-04-28 06:41

我正在创建一个数据库类型的对象,当找不到某个索引时,它会通过一个API获取信息,然后把这些信息保存到对象或文件中,并返回给用户。

我想通过重载 pandas DataFrame 的 .loc[x, y] 方法来实现这个功能,但我不知道该怎么做!

目前我有:

import pandas as pd
pd.set_option('io.hdf.default_format','table')

class DataBase(pd.DataFrame):
    """DataBase Object which can be updated by external api"""
    def __init__(self, path, api=None):
        super(DataBase, self).__init__(pd.read_hdf('store.h5','df'))
        self.api = api

我可能想要修改 __init__ 函数,加入一个 where 参数,这样我就可以只读取我需要的数据。

我想不出一个合适的方法来正确重载 .loc 方法!

另外,hdf5 只是其中一种存储方式。我希望能保留使用其他存储方法的能力,比如 SQL,甚至在必要时使用 CSV。

暂无标签

2 个回答

1

在上面的回答中补充一些内容,如果你以后需要对基本的 pandas 类进行扩展,可以重写一些构造函数的属性,以确保新创建的类在使用标准的 pandas 操作时能够正常工作,具体来说有以下几点:

  • _constructor:当操作结果的维度和原始数据相同的时候使用。
  • _constructor_sliced:当操作结果的维度比原始数据低一维时使用,比如对 DataFrame 的单列进行切片。
  • _constructor_expanddim:当操作结果的维度比原始数据高一维时使用,比如将 Series 转换为 DataFrame,或者将 DataFrame 转换为 Panel。

例如:

@property
def _constructor(self):
    return MyDataFrame 
4

loc 是一个属性,它会返回一个叫做 _loc 的名字,如果这个名字不是 None 的话;如果是 None,那么它会根据需要创建一个 pandas.core.indexing._LocIndexer。默认情况下,索引器可以访问创建它们的 DataFrame,所以当你在查找某个键时没有找到,可以修改这个 DataFrame。

你可以通过创建 DataFrame_LocIndexer 的子类来改变 DataFrame.loc 的行为,像这样。

class MyLocIndexer(_LocIndexer):    
    def __getitem__(self, key):
        try:                   
            return super().__getitem__(key)
        except KeyError:
            item = db.fetch_item(key)
            self[key] = item
            return item
            # `return self[key]' is better as it also works when accessing a 
            # whole axis

class MyDataFrame(DataFrame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._loc = MyLocIndexer(self, "loc")

上面的代码是用 python3 写的,如果你使用的是 python2,就需要修正 super 语句。

撰写回答