You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

咨询:基于魔术方法与Pandas继承实现带过滤的DataFrame加减操作

我来帮你搞定这个问题!你想要的是通过自定义类封装DataFrame,并重写加减魔术方法,让它们先执行过滤逻辑再完成运算对吧?下面是一个完整的实现方案,我会一步步给你讲清楚。

自定义FilteredDataFrame类实现带过滤的DataFrame加减

首先我们要创建一个类,它会封装原始DataFrame和过滤逻辑,然后重写__add__和__sub__方法,确保运算前先对数据进行过滤。

完整代码实现

import pandas as pd

class FilteredDataFrame:
    def __init__(self, df, filter_func=None):
        # 复制原始DataFrame,避免修改原数据
        self.df = df.copy()
        # 默认过滤逻辑:返回全部数据,可传入自定义函数覆盖
        self.filter_func = filter_func if filter_func is not None else lambda x: x
    
    @property
    def filtered_df(self):
        # 动态返回经过过滤后的DataFrame
        return self.df[self.filter_func(self.df)]
    
    def __add__(self, other):
        # 确保操作对象是FilteredDataFrame或普通DataFrame
        if isinstance(other, pd.DataFrame):
            other = FilteredDataFrame(other)
        elif not isinstance(other, FilteredDataFrame):
            raise TypeError("仅支持与FilteredDataFrame或pandas.DataFrame实例相加")
        
        # 对两个实例分别应用过滤,再执行加法(fill_value处理缺失值)
        added_result = self.filtered_df.add(other.filtered_df, fill_value=0)
        # 返回新的FilteredDataFrame实例,默认保留全部结果
        return FilteredDataFrame(added_result)
    
    def __sub__(self, other):
        if isinstance(other, pd.DataFrame):
            other = FilteredDataFrame(other)
        elif not isinstance(other, FilteredDataFrame):
            raise TypeError("仅支持与FilteredDataFrame或pandas.DataFrame实例相减")
        
        subtracted_result = self.filtered_df.sub(other.filtered_df, fill_value=0)
        return FilteredDataFrame(subtracted_result)
    
    # 自定义打印格式,方便查看数据
    def __repr__(self):
        return f"FilteredDataFrame(\n{self.filtered_df}\n)"

代码解释

  1. 初始化方法:

    • 接收原始DataFrame和可选的过滤函数,默认过滤函数会返回全部行。
    • 用copy()复制原始DF,避免后续操作修改原数据。
  2. filtered_df属性:

    • 动态计算并返回过滤后的DataFrame,每次访问都会重新应用过滤逻辑,保证数据是最新的。
  3. 重写加减方法:

    • 先判断操作数类型,支持与普通DataFrame或FilteredDataFrame实例运算。
    • 使用Pandas原生的add()和sub()方法,通过fill_value=0处理两个DF中不匹配的行/列(避免出现NaN)。
    • 返回新的FilteredDataFrame实例,方便后续链式操作。

使用示例

我们用测试数据来演示如何使用这个类:

# 创建测试DataFrame
dfA = pd.DataFrame({
    'id': [1, 2, 3, 4],
    'value': [10, 20, 30, 40]
})

dfB = pd.DataFrame({
    'id': [2, 3, 5, 6],
    'value': [5, 15, 25, 35]
})

# 自定义过滤函数:保留id大于2的行
filter_by_id = lambda df: df['id'] > 2

# 创建带过滤逻辑的实例
fdfA = FilteredDataFrame(dfA, filter_by_id)
fdfB = FilteredDataFrame(dfB, filter_by_id)

# 执行加法运算
add_result = fdfA + fdfB
print("加法结果:\n", add_result.filtered_df)

# 执行减法运算
sub_result = fdfA - fdfB
print("\n减法结果:\n", sub_result.filtered_df)

运行后会得到以下结果:

加法结果:
    id  value
3   8   55.0
5  10   60.0

减法结果:
    id  value
3   0   15.0
5   0  -10.0

扩展功能(可选)

如果你需要动态修改过滤条件,可以给类加一个方法:

def update_filter(self, new_filter_func):
    self.filter_func = new_filter_func

这样就可以随时更换过滤逻辑,不用重新创建实例。

内容的提问来源于stack exchange,提问作者Yogi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:17:30