@@ -236,12 +236,11 @@ def __get__(self, obj, cls):
236236CachedAccessor = Accessor
237237
238238
239- @doc (klass = "" , examples = "" , others = "" )
240239def _register_accessor (
241240 name : str , cls : type [NDFrame | Index ]
242241) -> Callable [[TypeT ], TypeT ]:
243242 """
244- Register a custom accessor on {klass} objects.
243+ Register a custom accessor on objects.
245244
246245 Parameters
247246 ----------
@@ -262,14 +261,14 @@ def _register_accessor(
262261
263262 Notes
264263 -----
265- This function allows you to register a custom-defined accessor class for {klass} .
264+ This function allows you to register a custom-defined accessor class for .
266265 The requirements for the accessor class are as follows:
267266
268267 * Must contain an init method that:
269268
270- * accepts a single {klass} object
269+ * accepts a single object
271270
272- * raises an AttributeError if the {klass} object does not have correctly
271+ * raises an AttributeError if the object does not have correctly
273272 matching inputs for the accessor
274273
275274 * Must contain a method for each access pattern.
@@ -281,7 +280,7 @@ def _register_accessor(
281280
282281 Examples
283282 --------
284- {examples}
283+
285284 """
286285
287286 def decorator (accessor : TypeT ) -> TypeT :
@@ -327,10 +326,73 @@ def decorator(accessor: TypeT) -> TypeT:
327326
328327
329328@set_module ("pandas.api.extensions" )
330- @doc (_register_accessor , klass = "DataFrame" , examples = _register_df_examples )
331329def register_dataframe_accessor (name : str ) -> Callable [[TypeT ], TypeT ]:
332- from pandas import DataFrame
330+ """
331+ Register a custom accessor on DataFrame objects.
332+
333+ Parameters
334+ ----------
335+ name : str
336+ Name under which the accessor should be registered. A warning is issued
337+ if this name conflicts with a preexisting attribute.
338+
339+ Returns
340+ -------
341+ callable
342+ A class decorator.
343+
344+ See Also
345+ --------
346+ register_dataframe_accessor : Register a custom accessor on DataFrame objects.
347+ register_series_accessor : Register a custom accessor on Series objects.
348+ register_index_accessor : Register a custom accessor on Index objects.
349+
350+ Notes
351+ -----
352+ This function allows you to register a custom-defined accessor class for DataFrame.
353+ The requirements for the accessor class are as follows:
354+
355+ * Must contain an init method that:
356+
357+ * accepts a single DataFrame object
358+
359+ * raises an AttributeError if the DataFrame object does not have correctly
360+ matching inputs for the accessor
361+
362+ * Must contain a method for each access pattern.
333363
364+ * The methods should be able to take any argument signature.
365+
366+ * Accessible using the @property decorator if no additional arguments are
367+ needed.
368+
369+ Examples
370+ --------
371+ An accessor that only accepts integers could
372+ have a class defined like this:
373+
374+ >>> @pd.api.extensions.register_dataframe_accessor("int_accessor")
375+ ... class IntAccessor:
376+ ... def __init__(self, pandas_obj):
377+ ... if not all(pandas_obj[col].dtype == 'int64' for col in pandas_obj.columns):
378+ ... raise AttributeError("All columns must contain integer values only")
379+ ... self._obj = pandas_obj
380+ ...
381+ ... def sum(self):
382+ ... return self._obj.sum()
383+ ...
384+ >>> df = pd.DataFrame([[1, 2], ['x', 'y']])
385+ >>> df.int_accessor
386+ Traceback (most recent call last):
387+ ...
388+ AttributeError: All columns must contain integer values only.
389+ >>> df = pd.DataFrame([[1, 2], [3, 4]])
390+ >>> df.int_accessor.sum()
391+ 0 4
392+ 1 6
393+ dtype: int64
394+ """
395+ from pandas import DataFrame
334396 return _register_accessor (name , DataFrame )
335397
336398
@@ -359,10 +421,71 @@ def register_dataframe_accessor(name: str) -> Callable[[TypeT], TypeT]:
359421
360422
361423@set_module ("pandas.api.extensions" )
362- @doc (_register_accessor , klass = "Series" , examples = _register_series_examples )
363424def register_series_accessor (name : str ) -> Callable [[TypeT ], TypeT ]:
364- from pandas import Series
425+ """
426+ Register a custom accessor on Series objects.
365427
428+ Parameters
429+ ----------
430+ name : str
431+ Name under which the accessor should be registered. A warning is issued
432+ if this name conflicts with a preexisting attribute.
433+
434+ Returns
435+ -------
436+ callable
437+ A class decorator.
438+
439+ See Also
440+ --------
441+ register_dataframe_accessor : Register a custom accessor on DataFrame objects.
442+ register_series_accessor : Register a custom accessor on Series objects.
443+ register_index_accessor : Register a custom accessor on Index objects.
444+
445+ Notes
446+ -----
447+ This function allows you to register a custom-defined accessor class for Series.
448+ The requirements for the accessor class are as follows:
449+
450+ * Must contain an init method that:
451+
452+ * accepts a single Series object
453+
454+ * raises an AttributeError if the Series object does not have correctly
455+ matching inputs for the accessor
456+
457+ * Must contain a method for each access pattern.
458+
459+ * The methods should be able to take any argument signature.
460+
461+ * Accessible using the @property decorator if no additional arguments are
462+ needed.
463+
464+ Examples
465+ --------
466+ An accessor that only accepts integers could
467+ have a class defined like this:
468+
469+ >>> @pd.api.extensions.register_series_accessor("int_accessor")
470+ ... class IntAccessor:
471+ ... def __init__(self, pandas_obj):
472+ ... if not pandas_obj.dtype == 'int64':
473+ ... raise AttributeError("The series must contain integer data only")
474+ ... self._obj = pandas_obj
475+ ...
476+ ... def sum(self):
477+ ... return self._obj.sum()
478+ ...
479+ >>> df = pd.Series([1, 2, 'x'])
480+ >>> df.int_accessor
481+ Traceback (most recent call last):
482+ ...
483+ AttributeError: The series must contain integer data only.
484+ >>> df = pd.Series([1, 2, 3])
485+ >>> df.int_accessor.sum()
486+ np.int64(6)
487+ """
488+ from pandas import Series
366489 return _register_accessor (name , Series )
367490
368491
@@ -394,8 +517,72 @@ def register_series_accessor(name: str) -> Callable[[TypeT], TypeT]:
394517
395518
396519@set_module ("pandas.api.extensions" )
397- @doc (_register_accessor , klass = "Index" , examples = _register_index_examples )
398520def register_index_accessor (name : str ) -> Callable [[TypeT ], TypeT ]:
399- from pandas import Index
521+ """
522+ Register a custom accessor on Index objects.
523+
524+ Parameters
525+ ----------
526+ name : str
527+ Name under which the accessor should be registered. A warning is issued
528+ if this name conflicts with a preexisting attribute.
529+
530+ Returns
531+ -------
532+ callable
533+ A class decorator.
534+
535+ See Also
536+ --------
537+ register_dataframe_accessor : Register a custom accessor on DataFrame objects.
538+ register_series_accessor : Register a custom accessor on Series objects.
539+ register_index_accessor : Register a custom accessor on Index objects.
540+
541+ Notes
542+ -----
543+ This function allows you to register a custom-defined accessor class for Index.
544+ The requirements for the accessor class are as follows:
545+
546+ * Must contain an init method that:
400547
548+ * accepts a single Index object
549+
550+ * raises an AttributeError if the Index object does not have correctly
551+ matching inputs for the accessor
552+
553+ * Must contain a method for each access pattern.
554+
555+ * The methods should be able to take any argument signature.
556+
557+ * Accessible using the @property decorator if no additional arguments are
558+ needed.
559+
560+ Examples
561+ --------
562+ An accessor that only accepts integers could
563+ have a class defined like this:
564+
565+ >>> @pd.api.extensions.register_index_accessor("int_accessor")
566+ ... class IntAccessor:
567+ ... def __init__(self, pandas_obj):
568+ ... if not all(isinstance(x, int) for x in pandas_obj):
569+ ... raise AttributeError("The index must only be an integer value")
570+ ... self._obj = pandas_obj
571+ ...
572+ ... def even(self):
573+ ... return [x for x in self._obj if x % 2 == 0]
574+ >>> df = pd.DataFrame.from_dict(
575+ ... {"row1": {"1": 1, "2": "a"}, "row2": {"1": 2, "2": "b"}}, orient="index"
576+ ... )
577+ >>> df.index.int_accessor
578+ Traceback (most recent call last):
579+ ...
580+ AttributeError: The index must only be an integer value.
581+ >>> df = pd.DataFrame(
582+ ... {"col1": [1, 2, 3, 4], "col2": ["a", "b", "c", "d"]}, index=[1, 2, 5, 8]
583+ ... )
584+ >>> df.index.int_accessor.even()
585+ [2, 8]
586+ """
587+ from pandas import Index
401588 return _register_accessor (name , Index )
0 commit comments