Package: pandas-flavor
Pandas FlavorThe easy way to write your own flavor of PandasPandas 0.23 added a (simple) API for registering accessors with Pandas objects.Pandas-flavor extends Pandas' extension API by:adding support for registering methods as well.making each of these functions backwards compatible with older versions of Pandas.What does this mean?It is now simpler to add custom functionality to Pandas DataFrames and Series.Import this package. Write a simple python function. Register the function using one of the following decorators.Why?Pandas is super handy. Its general purpose is to be a "flexible and powerful data analysis/manipulation library".Pandas Flavorallows you add functionality that tailors Pandas to specific fields or use cases.Maybe you want to add new write methods to the Pandas DataFrame? Maybe you want custom plot functionality? Maybe something else?Register accessorsAccessors (in pandas) are objects attached to a attribute on the Pandas DataFrame/Series
that provide extra, specific functionality. For example,pandas.DataFrame.plotis an
accessor that provides plotting functionality.Add an accessor by registering the function with the following decorator
and passing the decorator an accessor name.# my_flavor.pyimportpandas_flavoraspf@pf.register_dataframe_accessor('my_flavor')classMyFlavor(object):def__init__(self,data):self._data=datadefrow_by_value(self,col,value):"""Slice out row from DataFrame by a value."""returnself._data[self._data[col]==value].squeeze()Every dataframe now has this accessor as an attribute.importmy_flavor# DataFrame.df=pd.DataFrame(data={"x":[10,20,25],"y":[0,2,5]})# Print DataFrameprint(df)# x  y# 0  10  0# 1  20  2# 2  25  5# Access this functionalitydf.my_flavor.row_by_value('x',10)# x    10# y     0# Name: 0, dtype: int64To see this in action, check outpdvega,PhyloPandas, andpyjanitor!Register methodsUsing this package, you can attach functions directly to Pandas objects. No
intermediate accessor is needed.# my_flavor.pyimportpandas_flavoraspf@pf.register_dataframe_methoddefrow_by_value(df,col,value):"""Slice out row from DataFrame by a value."""returndf[df[col]==value].squeeze()importpandasaspdimportmy_flavor# DataFrame.df=pd.DataFrame(data={"x":[10,20,25],"y":[0,2,5]})# Print DataFrameprint(df)# x  y# 0  10  0# 1  20  2# 2  25  5# Access this functionalitydf.row_by_value('x',10)# x    10# y     0# Name: 0, dtype: int64Registered methods tracingThe pandas_flavor 0.5.0 release introducedtracing of the registered method calls. Now it is possible to add additional run-time logic around registered method execution which can be used for some support tasks. This extension was introduced
to allow visualization ofpyjanitormethod chains as implemented inpyjvizAvailable Methodsregister_dataframe_method: register a method directly with a pandas DataFrame.register_dataframe_accessor: register an accessor (and it's methods) with a pandas DataFrame.register_series_method: register a methods directly with a pandas Series.register_series_accessor: register an accessor (and it's methods) with a pandas Series.InstallationYou can install usingpip:pip install pandas_flavoror conda (thanks @ericmjl)!conda install -c conda-forge pandas-flavorContributingPull requests are always welcome! If you find a bug, don't hestitate to open an issue or submit a PR. If you're not sure how to do that, check out thissimple guide.If you have a feature request, please open an issue or submit a PR!TL;DRPandas 0.23 introduced a simpler API forextending Pandas. This API provided two key decorators,register_dataframe_accessorandregister_series_accessor, that enable users to registeraccessorswith Pandas DataFrames and Series.Pandas Flavor originated as a library to backport these decorators to older versions of Pandas (<0.23). While doing the backporting, it became clear that registeringmethodsdirectly to Pandas objects might be a desired feature as well.**It is likely that Pandas deliberately chose not implement to this feature. If everyone starts monkeypatching DataFrames with their custom methods, it could lead to confusion in the Pandas community. The preferred Pandas approach is to namespace your methods by registering an accessor that contains your custom methods.So how does method registration work?When you register a method, Pandas flavor actually creates and registers a (this is subtle, but important)custom accessor class that mimicsthe behavior of a method by:inheriting the docstring of your functionoverriding the__call__method to call your function.