"""Access data frame/series from context in ``.loc[]``, ``.iloc[]``, ``.assign()``, and others."""
from typing import Any, Callable, ClassVar, Dict, Iterable, Optional, Union, Tuple, Type
import pandas as pd
# The context in which the wrappers might be used
PdContext = Union[pd.DataFrame, pd.Series]
# Wrappers for attribute, item and operator access
class WrapperBase:
"""Base class for wrapping attribute, item or operator/method access."""
def __init__(self, name: str):
"""
Parameters
----------
name
Name of the accessed object member.
"""
self.name = name
def __repr__(self) -> str:
return f"<{type(self).__name__} {self.name}>"
def __call__(self, obj: Any, root_obj: PdContext) -> Any:
"""Access member of wrapped object.
Parameters
----------
obj
Anything that can be reached view item-, attribute-, or
method-calls from a ``~pandas.DataFrame`` or ``~pandas.Series``.
root_obj
The original data frame or series from the context.
Returns
-------
member
The referenced member of ``obj``.
"""
raise NotImplementedError("Must be implemented by a sub-class.")
def __getstate__(self) -> Dict[str, Any]:
return self.__dict__.copy()
def __setstate__(self, state:Dict[str, Any]):
self.__dict__.update(state)
class Attribute(WrapperBase):
"""Wrap ``df.column_name`` or similar access patterns."""
def __call__(self, obj, root_obj: PdContext) -> Any:
"""Access attribute of wrapped object.
Parameters
----------
obj
Anything that can be reached view item-, attribute-, or
method-calls from a ``~pandas.DataFrame`` or ``~pandas.Series``.
root_obj
The original data frame or series from the context.
Returns
-------
member
The referenced member of ``obj``.
"""
return getattr(obj, self.name)
def __str__(self):
return f".{self.name}"
class Item(WrapperBase):
"""Wrap ``df["column_name"]`` or similar access patterns."""
def __call__(self, obj, root_obj: PdContext):
"""Access item of wrapped object.
Parameters
----------
obj
Anything that can be reached view item-, attribute-, or
method-calls from a ``~pandas.DataFrame`` or ``~pandas.Series``.
root_obj
The original data frame or series from the context.
Returns
-------
member
The referenced member of ``obj``.
"""
return obj[self.name]
def __str__(self):
return f"[{self.name!r}]"
class Method(WrapperBase):
"""Wrap method and operator calls.
This can also be nested, i.e. use ``DF`` or ``S`` in method arguments.
Examples
--------
Operators::
DF["x"] <= other # or DF.x <= other
# dynamically create comparison predicate from the same data frame
DF["x"] <= DF["x"].mean()
# or use another column
DF["x"] <= DF["y"]
DF["x"] <= DF["y"].min()
Access series methods::
DF["x"].method() # or DF.x.method()
# You can also pass arguments.
DF["x"].clip(0)
DF["x"].clip(upper=0)
# You can use DF (or S) in the arguments to access the outer object
DF["x"].clip(DF["y"].min())
DF["x"].clip(upper=DF["y"].min())
"""
def __init__(self, name: str, *args: Any, **kwargs: Any):
"""
Parameters
----------
name
Method or operator name, e.g. `mean` or `__eq__`.
args, kwargs
(Optional) arguments for the method or operator, e.g. the second
argument for a binary operator.
"""
super().__init__(name)
self.args = args
self.kwargs = kwargs
def __repr__(self) -> str:
arg_reprs = (
[f"{a!r}" for a in self.args]
+ [f"{k}={a!r}" for k, a in self.kwargs.items()]
)
return f"<{type(self).__name__}: {self.name}({', '.join(arg_reprs)})>"
def __str__(self) -> str:
# Use shorter `str` representation for accessors and `repr` for the
# rest
fmt_arg = lambda a: str(a) if isinstance(a, AccessorBase) else repr(a)
arg_strs = (
[fmt_arg(a) for a in self.args]
+ [f"{k}={fmt_arg(a)}" for k, a in self.kwargs.items()]
)
return f".{self.name}({', '.join(arg_strs)})"
def _evaluate_method_arg(self, arg: Any, root_obj: PdContext):
"""Evaluatue any ``DF``- or ``S``-based arguments for the method
call.
This is needed to support things like (``DF['x'].mean()`` will be
evaluated with ``df``)::
df.assign(
y = DF['x'].clip(low=DF['x'].mean() - 0.5)
)
Parameters
----------
arg
The method argument.
root_obj
The dataframe or series to evaluate ``arg`` with.
Returns
-------
eval_arg
Evaluated method argument if the argument is ``DF`` or ``S``
based, else just ``arg``.
"""
if isinstance(arg, AccessorBase):
return arg(root_obj)
return arg
def __call__(self, obj: Any, root_obj: PdContext) -> Any:
"""Call method ``self.name`` on ``obj``.
Parameters
----------
obj
Anything that can be reached view item-,attribute- or
method-calls from a ``~pandas.DataFrame`` or ``~pandas.Series``.
root_obj
The original data frame or series from the context.
Returns
-------
result
The result of the method or operator call.
"""
op_meth = getattr(obj, self.name)
return op_meth(
*[self._evaluate_method_arg(arg, root_obj) for arg in self.args],
**{k: self._evaluate_method_arg(arg, root_obj) for k, arg in self.kwargs.items()}
)
def _add_dunder_operators(cls):
"""Dress class with all sensible comparison operations.
The class must implement a ``_operator_proxy`` method.
.. note::
This need to be applied on the concrete classes not the base class
to allow copying of docstrings.
"""
for op in [
"__abs__",
"__add__",
"__and__",
"__bool__",
"__contains__",
"__div__",
"__divmod__",
"__eq__",
"__floordiv__",
"__ge__",
"__gt__",
"__invert__",
"__le__",
"__lt__",
"__mul__",
"__ne__",
"__neg__",
"__not__",
"__or__",
"__pos__",
"__pow__",
"__sub__",
"__truediv__",
"__xor__",
]:
# Fix the closure of `op_wrap` to the current value of `op`. Without
# `fix_closure()` all created methods point to the last `op` value.
def fix_closure(op):
def op_wrap(self, *args, **kwargs):
return self._operator_proxy(op)(*args, **kwargs)
# Update method metadata to improve usablility
op_wrap.__name__ = op
orig_doc = None
orig_annot = None
for pd_cls in {pd.Series} | {cls.wrapped_cls}:
if hasattr(pd_cls, op):
a = getattr(pd_cls, op)
if not a.__doc__:
continue
op_wrap.__doc__ = a.__doc__
op_wrap.__annotations__ = a.__annotations__
break
return op_wrap
setattr(cls, op, fix_closure(op))
return cls
def _get_obj_attr_doc(obj_or_class: Any, attr: str):
"""Get doc-string for attribute ``attr`` of ``obj_or_class`` if it exists."""
if isinstance(attr,

程序员Chino的日记
- 粉丝: 3819
- 资源: 5万+
最新资源
- 基于氩气、空气、氧气填充床的DBD介质阻挡放电仿真研究-Comsol等离子体模块应用与沿面放电特性分析,氩气、空气与氧气填充床DBD介质阻挡放电的Comsol等离子体模块仿真研究:沿面放电特性分析
- 三相短路计算与潮流分析:基于MATLAB的程序实现,三相短路计算与潮流分析:基于MATLAB的程序设计与实现,三相短路计算,潮流计算,MATLAB程序 ,三相短路计算; 潮流计算; MATLAB程序
- 双向Buck-Boost变换器与DC-DC变换器的电压外环电流内环控制及其三种工作模式解析:恒功率、恒电流与稳压模式应用,双向Buck-Boost变换器与DC-DC变换器的电压外环电流内环控制模式及其
- DSP28335驱动下的三相逆变器电路设计与高效代码实现,DSP28335驱动的三相逆变器电路设计与优化代码实践,dsp28335三相逆变器电路加代码 ,dsp28335; 三相逆变器电路; 代码,D
- 各省市区明清进士人数数据
- 基于Maxwell软件的450W功率、内置式永磁同步电机技术参数详解:12槽10极切向设计,定子直径40mm,额定电流与转速详述,CAD绘制转子设计文件 ,基于Maxwell软件的12槽10极切向内置
- office 2016 自定义安装的工具
- 利用激光雷达观测验证ERA5、NORA3和NEWA的大风廓线-Tall wind speed profiles with Doppler wind lidars
- Delphi 12.3控件之TMS FlexCel Studio for VCL 3.21.exe
- Delphi 7 创建Access 数据库源代码
- 蚁群算法融合动态窗口法的路径规划算法研究:多动态障碍物的应用与挑战,蚁群算法结合动态窗口路径规划,多动态障碍环境下策略优化,蚁群算法融合动态窗口法路径规划算法 多动态障碍物 ,蚁群算法;动态窗口法;路
- 《95015网络安全应急响应分析报告(2024)》
- 基于STM32单片机的多级PWM调速直流电机控制系统设计:集成L298N驱动器、霍尔测速模块、液晶显示及多模式控制功能,基于L298N驱动与霍尔测速的STM32单片机直流电机PWM调速控制系统设计:按
- 基于Comsol的精确人体皮肤温度场计算模型:揭示正常代谢下皮肤温度分布规律,基于Comsol的人体皮肤温度场计算模型:探究正常代谢下皮肤温度分布,comsol 人体皮肤温度场计算模型,可以得到人体皮
- 2024人才薪资报告行业报告2024人才薪资报告
- 直流微电网多储能单元均衡控制策略:改进下垂控制实现不同容量蓄电池协调,快速均衡SOC并维持母线电压稳定,直流微电网多储能单元均衡控制策略:改进下垂控制实现不同蓄电池协调与SOC均衡,增加母线电压补偿环
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈


