Python中的重载 - pandas
我正在创建一个数据库类型的对象,当找不到某个索引时,它会通过一个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 语句。