是否可以为 pandas GroupBy 对象编写访问器?
Is it possible to write an accessor for pandas GroupBy objects?
我想知道是否可以为 GroupBy 对象实现 pandas api 访问器(如 https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.api.extensions.register_dataframe_accessor.html#pandas.api.extensions.register_dataframe_accessor)。
使用以下代码,我可以将访问器应用于组项目:
import pandas as pd
import numpy as np
@pd.api.extensions.register_dataframe_accessor("geo")
class GeoAccessor:
def __init__(self, pandas_obj):
self._obj = pandas_obj
@property
def center(self):
# return the geographic center point of this DataFrame
lat = self._obj.latitude
lon = self._obj.longitude
return (float(lon.mean()), float(lat.mean()))
if __name__ == "__main__":
ds = pd.DataFrame({"longitude": np.linspace(0, 10),
"latitude": np.linspace(0, 20)})
ds['grp'] = ds['longitude'].astype(int)
for g in ds.groupby(by='grp'):
print(g[1].geo.center)
这导致
(0.40816326530612246, 0.8163265306122449)
(1.4285714285714286, 2.857142857142857)
(2.4489795918367347, 4.8979591836734695)
(3.4693877551020407, 6.938775510204081)
(4.4897959183673475, 8.979591836734695)
(5.510204081632653, 11.020408163265307)
(6.530612244897959, 13.061224489795919)
(7.551020408163266, 15.102040816326532)
(8.571428571428573, 17.142857142857146)
(9.489795918367347, 18.979591836734695)
(10.0, 20.0)
现在,我如何使用类似于以下的语法直接执行此操作:
ds.groupby('grp').geo.center
我得到的错误信息是
ds.groupby(by='grp').geo.center
Traceback (most recent call last):
File "C:\.../ipykernel_11200/2937951017.py", line 1, in <module>
ds.groupby(by='grp').geo.center
File "C:\...\anaconda3\lib\site-packages\pandas\core\groupby\groupby.py", line 911, in __getattr__
raise AttributeError(
AttributeError: 'DataFrameGroupBy' object has no attribute 'geo'
你真的想 ds.groupby('grp').apply (lambda d: d.geo.center)
吗?
也许可以将其实现为访问器,但您必须借用 CachedAccessor 的源代码和 pandas 中的 _register_accessor,然后定义您的访问器对象,然后添加使用 _register_accessor 将其分配给 class 组。以此为例。 https://github.com/staircase-dev/piso/blob/master/piso/accessor.py
您的访问器对象将引用它所附加的 Groupby 对象。您想要定义 center
属性,它只是 returns Groupby 对象上 .apply(lambda d: d.geo.center)
的结果。不过,这似乎是语法糖,需要做很多工作。
我想知道是否可以为 GroupBy 对象实现 pandas api 访问器(如 https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.api.extensions.register_dataframe_accessor.html#pandas.api.extensions.register_dataframe_accessor)。
使用以下代码,我可以将访问器应用于组项目:
import pandas as pd
import numpy as np
@pd.api.extensions.register_dataframe_accessor("geo")
class GeoAccessor:
def __init__(self, pandas_obj):
self._obj = pandas_obj
@property
def center(self):
# return the geographic center point of this DataFrame
lat = self._obj.latitude
lon = self._obj.longitude
return (float(lon.mean()), float(lat.mean()))
if __name__ == "__main__":
ds = pd.DataFrame({"longitude": np.linspace(0, 10),
"latitude": np.linspace(0, 20)})
ds['grp'] = ds['longitude'].astype(int)
for g in ds.groupby(by='grp'):
print(g[1].geo.center)
这导致
(0.40816326530612246, 0.8163265306122449)
(1.4285714285714286, 2.857142857142857)
(2.4489795918367347, 4.8979591836734695)
(3.4693877551020407, 6.938775510204081)
(4.4897959183673475, 8.979591836734695)
(5.510204081632653, 11.020408163265307)
(6.530612244897959, 13.061224489795919)
(7.551020408163266, 15.102040816326532)
(8.571428571428573, 17.142857142857146)
(9.489795918367347, 18.979591836734695)
(10.0, 20.0)
现在,我如何使用类似于以下的语法直接执行此操作:
ds.groupby('grp').geo.center
我得到的错误信息是
ds.groupby(by='grp').geo.center
Traceback (most recent call last):
File "C:\.../ipykernel_11200/2937951017.py", line 1, in <module>
ds.groupby(by='grp').geo.center
File "C:\...\anaconda3\lib\site-packages\pandas\core\groupby\groupby.py", line 911, in __getattr__
raise AttributeError(
AttributeError: 'DataFrameGroupBy' object has no attribute 'geo'
你真的想 ds.groupby('grp').apply (lambda d: d.geo.center)
吗?
也许可以将其实现为访问器,但您必须借用 CachedAccessor 的源代码和 pandas 中的 _register_accessor,然后定义您的访问器对象,然后添加使用 _register_accessor 将其分配给 class 组。以此为例。 https://github.com/staircase-dev/piso/blob/master/piso/accessor.py
您的访问器对象将引用它所附加的 Groupby 对象。您想要定义 center
属性,它只是 returns Groupby 对象上 .apply(lambda d: d.geo.center)
的结果。不过,这似乎是语法糖,需要做很多工作。