Skip to content

Instantly share code, notes, and snippets.

@pjbull
Last active January 2, 2020 22:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pjbull/6c294176819b0251cad6e87ce96d6f5b to your computer and use it in GitHub Desktop.
Save pjbull/6c294176819b0251cad6e87ce96d6f5b to your computer and use it in GitHub Desktop.
pathlib.Path access for pandas series
from pathlib import Path
import pandas as pd
@pd.api.extensions.register_series_accessor("path")
@pd.api.extensions.register_index_accessor("path")
class PathAccessor:
def __init__(self, pandas_obj):
self._validate(pandas_obj)
self._obj = pandas_obj
@staticmethod
def _validate(obj):
[Path(x) for x in obj.values]
def __getattr__(self, attr):
apply_series = self._obj.to_series() if isinstance(self._obj, pd.Index) else self._obj
# check the type of this attribute on a Path object
attr_type = getattr(type(Path()), attr, None)
# if we're asking for a property, do the calculation and return the result
if isinstance(attr_type, property):
return apply_series.apply(lambda x: getattr(Path(x), attr))
# if we're asking for a function, return a callable method
elif isinstance(attr_type, (FunctionType, MethodType, LambdaType)):
def _callable(*args, **kwargs):
return apply_series.apply(lambda x: getattr(Path(x), attr)(*args, **kwargs))
return _callable
else:
raise AttributeError(f"Can't find or handle path attribute {attr}.")
# operators don't override correctly unless defined
def __truediv__(self, other):
return self.__getattr__("__truediv__")(other)
def __rtruediv__(self, other):
return self.__getattr__("__rtruediv__")(other)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment